Quote a cart
/v1/events/{slug}/tickets/quotePrice a cart exactly as reserve would, without holding inventory or creating anything. Call it as the cart changes to show the running total and the booking fee, and when the buyer types a promo code to tell them whether it worked.
The server is authoritative: the figures here are what reserve will charge for the same cart a moment later, subject to availability.
promoApplied is the answer to "did the code work". A wrong or exhausted code does not fail the request. When unlocksVisibility is true the code also reveals held-back stock, whether a whole gated ticket type or a single hidden tier it names: fetch ticket availability again with ?promo= to list it.
Send the same affiliateCode and artistId you will send on reserve, or a gated tier the buyer can legitimately see prices as unavailable here.
404 not_found for no visible reason.Request
curl -sS \
-X POST \
-H 'X-Grofomo-Key: pk_live_YOUR_PUBLISHABLE_KEY' \
-H 'Content-Type: application/json' \
-d '{"items":[{"releaseId":"9c7e5a3b-1f0d-4b2e-8a6c-4d2f0b8e6a14","quantity":2}],"promoCode":"EARLYBIRD"}' \
'https://api.grofomo.com/v1/events/summer-fest/tickets/quote?surface=web'Request body
itemsobject[]required- The cart to price. Same shape as reserve.
items[].releaseIduuidrequired- A release id from the ticket availability feed.
items[].quantitynumberrequired- Units of that release.
promoCodestring- The code the buyer typed. Read `promoApplied` to learn whether it worked.
affiliateCodestring- Send whatever you will send on reserve, so gated tiers price the same way here.
artistIduuid- Send whatever you will send on reserve, so gated tiers price the same way here.
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`.
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
{
"apiVersion": 1,
"data": {
"subtotalPennies": 22000,
"discountPennies": 2200,
"bookingFeePennies": 1535,
"totalPennies": 21335,
"currency": "GBP",
"promoApplied": true,
"appliedReleaseIds": [],
"discountType": "percentage",
"discountValue": 1000,
"unlocksVisibility": false
}
}subtotalPenniesnumber- Face value of the cart before discounts, in minor units.
discountPenniesnumber- Everything taken off (automatic quantity discount plus promo code), in minor units.
bookingFeePenniesnumber- The booking fee, in minor units.
totalPenniesnumber- What the buyer would pay, in minor units.
currencystring- ISO 4217 code every amount is in.
promoAppliedboolean- True when the promo code was valid and applied to this cart. False with a code sent means the code is wrong, expired, used up, or does not cover these tiers.
appliedReleaseIdsuuid[]- Release ids the promo discounts. Empty means every release in the cart.
discountType"percentage" | "fixed" | "none"- How the promo discounts: `percentage` of the tier price, a `fixed` amount, or `none`.
discountValuenumber- Basis points for percentage (1000 = 10%), minor units for fixed, 0 for none.
unlocksVisibilitybooleanmay be absent- True when the code also reveals hidden ticket types. Fetch the ticket availability feed again with `?promo=<code>` to list them.
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 event with that slug is published on this surface. Check the slug, and check you sent `?surface=web`.
bad_requestHTTP 400- The body did not match the schema.
unknown_releaseHTTP 400- A `releaseId` is not on this event or not visible to this caller.
not_on_saleHTTP 409- A release in the cart is closed, not yet open, or sold out.
per_order_minHTTP 400- Fewer units of a type than its `minPerOrder`.
per_order_maxHTTP 400- More units of a type than its `maxPerOrder`.
invalid_promoHTTP 400- The promo code does not exist or does not cover this cart.
expired_promoHTTP 400- The promo code is outside its dates.
promo_used_upHTTP 409- The promo code has reached its use limit.
promo_requiredHTTP 400- A release in the cart is gated behind a promo code and none was sent.
affiliate_requiredHTTP 400- A release in the cart is affiliate-gated and no valid `affiliateCode` was sent.
cancelledHTTP 410- The event has been cancelled.
Notes
- Rate limited to roughly 60 requests per minute per caller. Guidance, not a contract — see caching and rate limits.
Cache-Control: no-store