Complete a free order
POST
/v1/events/{slug}/tickets/orders/{checkoutToken}/complete-freeFinish 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