Convova
Sell on your own site

Sell on your own site

Read the program and sell tickets from your website, with no key.

The public API is at /api/public/v1. No key, no session, open to any origin. It sees published events only; a draft and an unknown address both answer 404. The full reference with request samples is under API reference, and a markdown quickstart for people and models is at /docs/quickstart.md.

Every response

{ "data": { }, "error": null, "pagination": null }

data holds the answer, or null when error holds the message. pagination is { offset, limit, total, hasMore } when you asked for a page with offset or limit, null otherwise. A list without them returns up to 1,000 items; limit is at most 100.

StatusMeaning
400The body or query did not validate. error names the first problem.
401Prove the email first.
404No such thing, or not published.
409The request contradicts the current state.
429Too many requests. Retry-After says how many seconds to wait.
502Stripe or the email provider failed.
500Something broke on our side.

Reading

Your website renders its own event pages from these:

GET events                              published events
GET events/{slug}                       one event
GET events/{slug}/sessions              the schedule, each session with its people and tags
GET events/{slug}/sessions/{id}
GET events/{slug}/contributors          people on the program
GET events/{slug}/contributors/{id}
GET events/{slug}/organizations         companies on the program
GET events/{slug}/organizations/{id}
GET events/{slug}/session-tags          the three tag lists
GET events/{slug}/contributor-tags
GET events/{slug}/organization-tags
GET events/{slug}/ticket-types          the badge labels
GET events/{slug}/products              what is for sale, each with its price and onSale,
                                        which is false once the event has ended
GET hosts/{hostSlug}                    the host and its published events
GET openapi.json                        the reference as OpenAPI

Hidden items never appear. A hidden product appears only when asked for by id with ?include=, so you can sell it from a private link.

Selling

The same flow the Convova checkout uses:

  1. POST events/{slug}/orders/quote with the cart returns the totals. A cart is a list of tickets, each a product id with its add-ons, plus an optional promo code. POST events/{slug}/coupons/validate answers whether a code works for this cart and what it saves.
  2. The buyer proves their email. POST events/{slug}/checkout/start with the email sends a six-digit code. POST events/{slug}/checkout/verify with the email and the code returns a buyerToken that is good for a short while. A buyer who is signed in to Convova can skip this; the session proves them.
  3. POST events/{slug}/orders with the cart and the buyerToken creates the order, holds its units, and returns orderId and checkoutUrl. Send the buyer to checkoutUrl; it is Stripe's page. A free order has no checkoutUrl and is paid at once.
  4. GET events/{slug}/orders/{orderId} returns the status: pending, paid, expired, or refunded. Poll it after the buyer comes back. The id is the only key to it, and it carries no personal data.
  5. POST events/{slug}/orders/{orderId}/cancel releases the hold when the buyer leaves Stripe's page. An order that is not paid in time expires on its own.

Payment is recorded by Stripe's webhook, never by the browser, and the tickets go to the buyer by email.

Limits

Quotes and coupon checks allow 30 calls a minute per address; asking for a code and creating an order are braked per address too, and order creation has a global ceiling as well. A code lasts ten minutes, allows three tries, and can be sent again after a minute. One buyer can have only a few open holds in an event at a time. Over a limit the answer is 429 with Retry-After.

On this page