Seller API
Manage your inventory on the Ticketero marketplace. Publish tickets, fulfill orders, track payments and receive signed webhooks.
The Seller API gives partners programmatic access to manage their inventory in real time on the Ticketero marketplace: list events from our catalog, publish and update tickets, fulfill orders, track payments, and receive signed webhook notifications for every relevant change. Whether you are building a sync engine, an internal dashboard or fully automated workflows, it gives you everything required to operate at scale.
All endpoints are authenticated with a Bearer token and protected by per-route rate limits.
This is a separate surface from the Buyer API. Explore every endpoint live in the Seller API Reference.
Base URL & authentication
https://production.ticketero.co/api # production
https://sandbox.ticketero.co/api # sandbox
Seller endpoints live under /broker. Every request needs the Bearer token Ticketero
issued you:
curl https://production.ticketero.co/api/broker/profile \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"
Tokens do not expire automatically, keep yours secret. If it is compromised, contact Ticketero to rotate it.
Typical integration flow
The endpoints chain together: the id you get from one call feeds into the next.
- Find the event in our catalog:
GET /broker/events?q=..., each result has anid. If the event does not exist yet, submit it withPOST /broker/events(returns anidplusapproval_status: "pending"). Wait for theevent.approvedwebhook before posting tickets. - List your inventory for that event:
GET /broker/tickets?event_id={id}. - Create a ticket:
POST /broker/ticketswithevent_idfrom step 1. The response gives you aticket_id, persist it; every later call references the ticket by it. Send your ownexternal_idto make retries safe (a repeatPOSTreturns409with the existing ticket). - Update inventory:
PUT /broker/tickets/{ticket_id}(full update), or the shortcutsPATCH /broker/tickets/{ticket_id}/stock,/price,/status. A ticket held by a checkout in progress is locked and rejects writes with409, see Locked tickets. - Receive orders: when a customer buys, you get an
order.createdwebhook. ThenGET /broker/orders/{id}to read it, andPOST /broker/orders/{id}/deliverto upload the tickets and mark it delivered (pending-delivery→delivered). - Payments: once Ticketero settles the order you receive a
payment.confirmedwebhook; query history viaGET /broker/payments.
Identifiers cheat-sheet
| Returned by | Use as |
|---|---|
id from GET /events (or POST /events) |
event_id in POST /tickets; event_id query of GET /tickets |
id from GET /venues |
venue.id in POST /events |
ticket_id from POST /tickets |
path param of GET/PUT/PATCH/DELETE /tickets/{ticket_id} |
external_id you choose |
external_id in POST /tickets; external_id query of GET /tickets |
id from the order.created webhook (data.id) |
path param of GET/POST /orders/{id}/... |
Webhooks
Register HTTPS URLs with POST /broker/webhooks and Ticketero sends signed POSTs whenever
events occur. Each delivery carries an X-Ticketero-Signature header (HMAC-SHA256 over the
raw request body, using the secret returned at registration).
The secret is returned once, at registration. Copy it then, verify every delivery server-side, and reject unsigned or mismatched requests.
Events
Subscribe to any subset of these on POST /broker/webhooks:
| Event | Fired when | data shape |
|---|---|---|
order.created |
A customer buys one of your tickets | order object + recipient |
order.updated |
An order you own changes | order object |
order.delivered |
You deliver an order (POST /orders/{id}/deliver) |
order object + booking, delivery_method, delivered_at |
order.cancelled |
Ticketero cancels an order you own | order object (status: "cancelled") |
payment.confirmed |
Ticketero records a payment for your delivered orders | payment object |
ticket.disabled |
One of your tickets is deactivated | ticket_id, external_id, event_id, reason, disabled_at |
event.approved |
An event you submitted is approved | event_id, title, date, time, approved_at |
Payload shape
Every delivery is the same envelope: event, created_at, and an event-specific data:
{ "event": "order.created", "created_at": "2026-04-22T19:14:00+00:00", "data": { } }
Order events
For order.created, order.updated, order.delivered and order.cancelled, data is the
same order object as GET /orders/{id}, so you can act on the webhook without a follow-up
GET. data.id is the order id (there is no order_id), and Ticketero’s markup is never
included.
{
"event": "order.created",
"created_at": "2026-06-05T17:58:01-06:00",
"data": {
"id": 245243,
"order": "A1B2C3",
"quantity": 1,
"price": 3,
"total": 3,
"currency": "USD",
"status": "pending-delivery",
"recipient": { "name": "Carlos Smeke", "email": "[email protected]", "phone": "+1 3055550100" },
"ticket": {
"id": "211451505",
"external_id": "BRK-INV-0001",
"section": "Testing Sales 2",
"row": "Last",
"low_seat": "1000",
"high_seat": "1014",
"price": 3,
"currency": "USD",
"delivery_date": "2026-03-10T06:00:00.000000Z",
"delivery_method": "e-ticket",
"notes": ""
},
"event": {
"name": "Ahab The Ticket Whaler Presents Safe Ticket Whaling",
"date": "2026-12-25",
"time": "03:03 PM",
"datetext": "Friday, December 25, 2026",
"datetime": "2026-12-25 15:03",
"venue_name": "Webster Theater",
"country": "United States of America",
"state": "Connecticut",
"city": "Hartford"
},
"payment_date": null,
"payment_status": "unpaid",
"delivery_data": "Delivery details will appear here once you deliver the tickets via POST /orders/{id}/deliver."
}
}
Per-event extras on top of the order object:
data.ticket.idis the sameticket_idyou got fromPOST /ticketsanddata.ticket.external_idis the id you supplied; use either to reconcile the sale against your inventory.data.orderis a short 6-character code identifying the buyer’s checkout. Orders bought together in one checkout share the sameordercode, so you can group a multi-ticket purchase. Returned on every order object (GET /orders,GET /orders/{id}and theorder.*webhooks); may benull.order.createdcarriesdata.recipient({name, email, phone}): who you must deliver to.order.deliveredcarriesbooking,delivery_method,delivered_at, anddata.delivery_databecomes the object you submitted ({ "files": [{ "url", "name", "source" }] }) instead of the placeholder string.order.cancelledsetsstatus: "cancelled";delivery_datastays a placeholder string.
ticket.disabled
Fired when one of your tickets is deactivated (e.g. PATCH /tickets/{id}/status → inactive).
reason is null unless a reason was supplied.
{
"event": "ticket.disabled",
"created_at": "2026-06-08T12:50:45-06:00",
"data": {
"ticket_id": "219561517",
"external_id": "BRK-INV-0001",
"event_id": 168126800,
"reason": null,
"disabled_at": "2026-06-08T12:50:45-06:00"
}
}
event.approved
Dispatched only to the broker that originally submitted the event, once it’s approved.
{
"event": "event.approved",
"created_at": "2026-04-22T19:14:00+00:00",
"data": {
"event_id": 169133082,
"title": "Ahab The Ticket Whaler Presents Safe Ticket Whaling",
"date": "2026-12-25",
"time": "20:00:00",
"approved_at": "2026-04-22T19:14:00+00:00"
}
}
payment.confirmed
Sent when Ticketero records a settlement against one or more of your delivered orders.
The data object uses the same field names as the payment resource from GET /broker/payments,
so one parser works on both. orders is the list of orders_broker ids the payment covers
(same shape as the REST list endpoint); payment_reference and voucher may be null.
{
"event": "payment.confirmed",
"created_at": "2026-06-08T12:00:00-06:00",
"data": {
"id": 85,
"payment_method": "bank_transfer",
"payment_reference": "WIRE-2026-0042",
"amount": 181.01,
"currency": "USD",
"voucher": null,
"orders": [245241, 245242],
"created_at": "2026-06-08T12:00:00-06:00"
}
}
Sandbox/test deliveries set data.test: true: ignore them. POST /webhooks/{id}/test fires a
full synthetic order.created (a complete order shape with fake values like id: 0,
order: "TEST01" and 2099 dates) so you can validate your parser end-to-end before going live.
Locked tickets
While a buyer is checking out one of your listings, Ticketero holds it and the ticket becomes
locked. A locked ticket cannot be modified: PUT /tickets/{ticket_id},
PATCH /tickets/{ticket_id}/price, /stock, /status and DELETE /tickets/{ticket_id} all
return 409:
{
"message": "Ticket is locked by an in-progress sale and cannot be modified. Try again later.",
"locked": true
}
The lock is temporary and clears on its own once the sale completes or the checkout expires. It exists so a price or stock change cannot land mid-sale and break a purchase already in flight.
Every ticket payload carries a locked boolean (GET /tickets, GET /tickets/{ticket_id}), so a
sync job can skip locked listings up front instead of retrying blindly:
const { data } = await get("/broker/tickets?event_id=" + eventId);
const syncable = data.filter((t) => !t.locked); // locked ones retry on the next pass
If you do hit a 409, do not loop on it. Queue the change and retry on your next sync cycle;
a checkout hold is short-lived.
Sandbox accounts
If your account is provisioned for sandbox testing:
GET /eventsalways returns a single dedicated test event.POST /ticketsandPOST /tickets/bulkonly accept the test event id, any otherevent_idis rejected with422.POST /eventsis disabled (403).- Every other endpoint behaves like production.
Rate limits
| Bucket | Limit |
|---|---|
broker-read |
240 req/min |
broker-write |
60 req/min |
broker-bulk (only POST /tickets/bulk) |
10 req/min |
Where to next
- Seller API Reference: every endpoint, with a live “Try it”.
- Errors & responses: the shared error shape and status codes.

API