Grofomo API
Browse the docs

Examples use a fictional festival, summer-fest. Sign in at events.grofomo.com and they switch to your own events.

Complete a free order

POST/v1/events/{slug}/tickets/orders/{checkoutToken}/complete-free

Finish an order whose totalPennies is zero: a free tier, or a code that discounted everything. Tickets are issued and the confirmation email sent at once, so there is nothing to poll.

Refused with payment_required when the order has anything to pay or is on a payment plan; that order goes through pay. Safe to retry: a second call returns the same result.

Send ?surface=webOmit it and the request is treated as coming from the mobile app, which is gated on a different visibility setting — so a perfectly live event can return 404 not_found for no visible reason.

Request

curl -sS \
  -X POST \
  -H 'X-Grofomo-Key: pk_live_YOUR_PUBLISHABLE_KEY' \
  'https://api.grofomo.com/v1/events/summer-fest/tickets/orders/YzNhMWU1ZDctOWIyZi00ZTZhLThjMGQtMmY0YjZhOGMwZTEyOjE3ODk2NDM2MDAwMDA6dGt0LWNoZWNrb3V0.ZXhhbXBsZS1zaWduYXR1cmU/complete-free?surface=web'

Path parameters

slugstringrequired
The event's URL slug. Globally unique. It can change if the organiser renames the event, but an old slug keeps reaching the same event, so a stored one never breaks. Example: `summer-fest`.
checkoutTokenstringrequired
The order's `checkoutToken` from the reserve response. It authorises this checkout only and expires a day after the reserve; keep it out of logs and analytics. Example: `YzNhMWU1ZDctOWIyZi00ZTZhLThjMGQtMmY0YjZhOGMwZTEyOjE3ODk2NDM2MDAwMDA6dGt0LWNoZWNrb3V0.ZXhhbXBsZS1zaWduYXR1cmU`.

Query parameters

surface'web'required
Must be `web` for a website. Omit it and you get the mobile-app surface, which is gated on a different visibility setting — so a perfectly live event can return 404. Example: `web`.

Response

200 OK
{
  "apiVersion": 1,
  "data": {
    "completed": true
  }
}
completedtrue
The free order is finalized: tickets issued and the confirmation email on its way. Replay-safe - retrying returns this again.
Generated from FreeOrderCompletionResponse

Errors

unauthorizedHTTP 401
No key was sent and the organiser requires one — or the key is invalid, revoked, belongs to another organisation, or is scoped to a different event.
origin_not_allowedHTTP 403
Your site's domain is not on the organiser's allowed list. Browser calls only: a server sends no Origin header and is unaffected.
not_foundHTTP 404
No order for that `checkoutToken` on this event (or the token has expired), or no event with that slug on this surface.
details_requiredHTTP 409
The buyer's details have not been sent yet. Call the details endpoint first.
expiredHTTP 409
The 15-minute hold has ended. Start again from reserve.
order_not_openHTTP 409
The order is no longer `reserved`: it has been paid, completed or cancelled.
payment_requiredHTTP 409
The order has something to pay. Use pay.

Notes

  • Rate limited to roughly 20 requests per minute per caller. Guidance, not a contract — see caching and rate limits.
  • Cache-Control: no-store