Draft API. Endpoints may change before general availability.

API reference

Every endpoint, with what it's for, what to send, and what you get back. All examples are real requests you can paste into a terminal once EVENTTICKETS_KEY holds your test key.

New here? Start with the Quickstart, and skim API basics for keys, errors, retries and paging.

Events

An event is what you sell tickets for: a one-off night, or one event over several days like a festival. It holds the venue and total capacity, its days, its ticket types (each with prices), and any add-ons. Events on different dates can be grouped into a series.

Create an event

POST/v1/events

Makes a new event as a draft. Drafts can't be bought yet, so you can check everything first. When you're ready, put it on sale with Change an event.

The currency is your account's currency. The event gets one day (starts_at) and one ticket type, General admission, holding the prices you sent. For a multi-day event, add days with Add a day and passes or day tickets with Add a ticket type.

The response is the full event, including each price's breakdown.

Body

namestringrequired
What the event is called.
starts_atdaterequired
When it starts, for example 2026-11-14T22:00:00Z.
tiersarray of pricesrequired
At least one price (fields below), in the order they should sell. They become the prices of a General admission ticket type.
doors_atdateoptional
When doors open, if different.
venuestringoptional
Venue name.
addressstringoptional
Street address.
citystringoptional
City.
descriptionstringoptional
Longer text for your own pages.
capacityintegeroptional
Most tickets the whole event can sell, across every tier. Leave out for no limit.
max_per_orderintegeroptional
Most tickets one buyer can get in one go, 1 to 50. Default 10.
fee_payerbuyer | organiseroptional
Who pays our booking fee. Default buyer.
door_modesingle | reentry | in_outoptional
Re-entry at the door. single: each ticket gets in once per day. reentry: scan again to go back in. in_out: staff scan people in and out. Default single.
series_ididoptional
Put the event in a series.

Request

curl https://api.eventtickets.dev/v1/events \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Harbour Nights",
    "starts_at": "2026-11-14T22:00:00Z",
    "venue": "The Harbour Rooms",
    "city": "Bristol",
    "capacity": 400,
    "tiers": [
      { "label": "Early bird", "price": 800, "capacity": 100 },
      { "label": "Standard",   "price": 1200 }
    ]
  }'

Response

{
  "id": "evt_3f9a1c2b7d4e5f60",
  "object": "event",
  "livemode": false,
  "name": "Harbour Nights",
  "slug": "harbour-nights",
  "description": null,
  "venue": "The Harbour Rooms",
  "address": null,
  "city": "Bristol",
  "starts_at": "2026-11-14T22:00:00+00:00",
  "doors_at": null,
  "ends_at": null,
  "timezone": "Europe/London",
  "currency": "gbp",
  "capacity": 400,
  "max_per_order": 10,
  "fee_payer": "buyer",
  "door_mode": "single",
  "series_id": null,
  "status": "draft",
  "created_at": "2026-10-04T09:12:44+00:00",
  "buy_url": "https://pay.eventtickets.dev/e/evt_3f9a1c2b7d4e5f60",
  "tickets_issued": 0,
  "tickets_checked_in": 0,
  "sessions": [
    {
      "object": "session",
      "id": "ses_2a7c4e9b1d3f5a80",
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "label": "Main",
      "starts_at": "2026-11-14T22:00:00+00:00",
      "doors_at": null,
      "ends_at": null
    }
  ],
  "ticket_types": [
    {
      "id": "tt_5d1e7f2a9b3c4d60",
      "object": "ticket_type",
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "name": "General admission",
      "description": null,
      "session_ids": ["ses_2a7c4e9b1d3f5a80"],
      "position": 0,
      "hidden": false,
      "sold": 0,
      "active_tier_id": "tier_8a2b6c4d1e9f3a70"
    }
  ],
  "tiers": [
    {
      "id": "tier_8a2b6c4d1e9f3a70",
      "object": "tier",
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "label": "Early bird",
      "price": 800,
      "currency": "gbp",
      "capacity": 100,
      "sold": 0,
      "state": "active",
      "active": true,
      "ends_at": null,
      "position": 0,
      "hidden": false,
      "ticket_type_id": "tt_5d1e7f2a9b3c4d60",
      "booking_fee": 54,
      "buyer_pays": 854,
      "organiser_receives": 800
    }
  ],
  "addons": []
}

Needs the events:write permission on your key.

List events

GET/v1/events

Your events, newest first. Use it to show an events page on your site. List items don't include tiers; get one event for those.

Query string

statusstringoptional
Only events with this status: draft, on_sale, paused, ended or cancelled.
limitintegeroptional
How many to return, 1 to 100. Default 20.
starting_afteridoptional
For the next page: the id of the last object you received. See API basics › Lists.

Request

curl "https://api.eventtickets.dev/v1/events?status=on_sale" -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "list",
  "data": [
    { "id": "evt_3f9a1c2b7d4e5f60", "object": "event", "name": "Harbour Nights", "status": "on_sale", "...": "" }
  ],
  "has_more": false
}

Needs the events:read permission on your key.

Get one event

GET/v1/events/:id

Everything about one event: its days, its ticket types, their prices with how many have sold and which is on sale now ("active": true), and its add-ons. Each price has buyer_pays, so you can show the exact price including the booking fee.

Request

curl https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "id": "evt_3f9a1c2b7d4e5f60",
  "object": "event",
  "livemode": false,
  "name": "Harbour Nights",
  "slug": "harbour-nights",
  "description": null,
  "venue": "The Harbour Rooms",
  "address": null,
  "city": "Bristol",
  "starts_at": "2026-11-14T22:00:00+00:00",
  "doors_at": null,
  "ends_at": null,
  "timezone": "Europe/London",
  "currency": "gbp",
  "capacity": 400,
  "max_per_order": 10,
  "fee_payer": "buyer",
  "door_mode": "single",
  "series_id": null,
  "status": "draft",
  "created_at": "2026-10-04T09:12:44+00:00",
  "buy_url": "https://pay.eventtickets.dev/e/evt_3f9a1c2b7d4e5f60",
  "tickets_issued": 0,
  "tickets_checked_in": 0,
  "sessions": [
    {
      "object": "session",
      "id": "ses_2a7c4e9b1d3f5a80",
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "label": "Main",
      "starts_at": "2026-11-14T22:00:00+00:00",
      "doors_at": null,
      "ends_at": null
    }
  ],
  "ticket_types": [
    {
      "id": "tt_5d1e7f2a9b3c4d60",
      "object": "ticket_type",
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "name": "General admission",
      "description": null,
      "session_ids": ["ses_2a7c4e9b1d3f5a80"],
      "position": 0,
      "hidden": false,
      "sold": 0,
      "active_tier_id": "tier_8a2b6c4d1e9f3a70"
    }
  ],
  "tiers": [
    {
      "id": "tier_8a2b6c4d1e9f3a70",
      "object": "tier",
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "label": "Early bird",
      "price": 800,
      "currency": "gbp",
      "capacity": 100,
      "sold": 0,
      "state": "active",
      "active": true,
      "ends_at": null,
      "position": 0,
      "hidden": false,
      "ticket_type_id": "tt_5d1e7f2a9b3c4d60",
      "booking_fee": 54,
      "buyer_pays": 854,
      "organiser_receives": 800
    }
  ],
  "addons": []
}

Needs the events:read permission on your key.

Change an event, or put it on sale

PATCH/v1/events/:id

Send only the fields you want to change. Everything else stays as it is. To edit tickets, prices or add-ons, use their endpoints below. series_id moves the event into a series, or out of one with null.

The allowed status moves are: draft → on_sale, on_sale ⇄ paused, and anything still running → ended or cancelled. Going on sale needs at least one visible ticket type with a visible price.

Body

statusstringoptional
on_sale to start selling, paused to stop for now, ended or cancelled to finish. Ended and cancelled are final.
…optional
Any field from Create an event except tiers. Only what you send is changed. On a multi-day event, change days with the day endpoints instead of starts_at.

Request

curl -X PATCH https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60 \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "on_sale" }'

Response

{ "id": "evt_3f9a1c2b7d4e5f60", "object": "event", "status": "on_sale", "...": "the full event" }

Needs the events:write permission on your key.

Sales and check-in numbers

GET/v1/events/:id/stats

The numbers for a dashboard or a "nearly sold out" banner. gross_sales is what buyers paid, fees is our booking fee, and revenue is what you receive. Tickets include guest list.

Request

curl https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60/stats -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "event_stats",
  "event_id": "evt_3f9a1c2b7d4e5f60",
  "currency": "gbp",
  "capacity": 400,
  "tickets_issued": 212,
  "tickets_checked_in": 0,
  "orders_paid": 118,
  "orders_refunded": 2,
  "gross_sales": 226540,
  "fees": 12740,
  "revenue": 213800,
  "tiers": [
    { "id": "tier_8a2b6c4d1e9f3a70", "label": "Early bird", "sold": 100, "capacity": 100, "state": "sold_out" },
    { "id": "tier_9b3c7d5e2f0a4b81", "label": "Standard", "sold": 112, "capacity": null, "state": "active" }
  ]
}

Needs the events:read permission on your key.

Copy an event to new dates

POST/v1/events/:id/copies

For a weekly night or a run of shows. Each copy is a separate draft event with the same details, door setting, days, ticket types, prices and add-ons, and nothing sold. They go in the event's series; if it isn't in one, a series is made with the event's name.

Body

startsarray of datesrequired
Start times for the copies' first day, up to 52. Their other days and price end dates move by the same amount.

Request

curl https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60/copies \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "starts": ["2026-11-12T19:30:00Z", "2026-11-19T19:30:00Z"] }'

Response

{
  "object": "series",
  "id": "ser_8b4d2f6a1c3e5b70",
  "name": "Comedy Thursdays",
  "url": "https://pay.eventtickets.dev/s/ser_8b4d2f6a1c3e5b70",
  "...": "",
  "created": [
    { "id": "evt_4a0b2d3c8e5f6a71", "object": "event", "status": "draft", "...": "" },
    { "id": "evt_5b1c3e4d9f6a7b82", "object": "event", "status": "draft", "...": "" }
  ]
}

Needs the events:write permission on your key.

Days

An event's days (in the API, sessions). Every event has at least one. A multi-day event has several, and each ticket type says which days it gets people in on. One QR code per ticket works on every day it covers, and the door checks it in once per day.

List an event's days

GET/v1/events/:id/sessions

In date order. The event's own starts_at and ends_at follow its first and last day.

Request

curl https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60/sessions -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "list",
  "data": [
    {
      "object": "session",
      "id": "ses_2a7c4e9b1d3f5a80",
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "label": "Main",
      "starts_at": "2026-11-14T22:00:00+00:00",
      "doors_at": null,
      "ends_at": null
    }
  ],
  "has_more": false
}

Needs the events:read permission on your key.

Add a day

POST/v1/events/:id/sessions

Tickets already sold keep the days they were bought for, even if you add this day to their ticket type.

Body

labelstringrequired
What staff and buyers see, like Saturday or Night 2.
starts_atdaterequired
When it starts.
doors_atdateoptional
When doors open.
ends_atdateoptional
When it ends.
ticket_type_idsarray of idsoptional
Ticket types that should also get people in on this day, like a weekend pass.

Request

curl https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60/sessions \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Saturday",
    "starts_at": "2026-11-15T12:00:00Z",
    "ticket_type_ids": ["tt_5d1e7f2a9b3c4d60"]
  }'

Response

{ "object": "session", "id": "ses_3b8d5f0c2e4a6b91", "label": "Saturday", "...": "" }

Needs the events:write permission on your key.

Get one day

GET/v1/sessions/:id

One day of an event.

Request

curl https://api.eventtickets.dev/v1/sessions/ses_2a7c4e9b1d3f5a80 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "session",
  "id": "ses_2a7c4e9b1d3f5a80",
  "event_id": "evt_3f9a1c2b7d4e5f60",
  "label": "Main",
  "starts_at": "2026-11-14T22:00:00+00:00",
  "doors_at": null,
  "ends_at": null
}

Needs the events:read permission on your key.

Change a day

PATCH/v1/sessions/:id

Send only what changes.

Body

labelstringoptional
A new name.
starts_atdateoptional
A new start.
doors_atdateoptional
A new doors time, or null.
ends_atdateoptional
A new end, or null.

Request

curl -X PATCH https://api.eventtickets.dev/v1/sessions/ses_2a7c4e9b1d3f5a80 \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "label": "Friday" }'

Response

{ "object": "session", "id": "ses_2a7c4e9b1d3f5a80", "label": "Friday", "...": "" }

Needs the events:write permission on your key.

Remove a day

DELETE/v1/sessions/:id

Only days that no ticket covers (guest list included) can be removed, and an event keeps at least one. A ticket type that only covers this day has to be deleted first.

Request

curl -X DELETE https://api.eventtickets.dev/v1/sessions/ses_3b8d5f0c2e4a6b91 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{ "id": "ses_3b8d5f0c2e4a6b91", "object": "session", "deleted": true }

Needs the events:write permission on your key.

Ticket types

What buyers choose between: General admission, VIP, Full pass, Saturday. Each ticket type covers some of the event's days and has one or more prices that sell in order, like Early bird then Standard. Every event has at least one.

List an event's ticket types

GET/v1/events/:id/ticket_types

In the order buyers see them. active_tier_id is the price on sale now; the prices themselves are the tiers with this ticket_type_id.

Request

curl https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60/ticket_types -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "list",
  "data": [
    {
      "id": "tt_5d1e7f2a9b3c4d60",
      "object": "ticket_type",
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "name": "General admission",
      "description": null,
      "session_ids": ["ses_2a7c4e9b1d3f5a80"],
      "position": 0,
      "hidden": false,
      "sold": 0,
      "active_tier_id": "tier_8a2b6c4d1e9f3a70"
    }
  ],
  "has_more": false
}

Needs the events:read permission on your key.

Add a ticket type with its prices

POST/v1/events/:id/ticket_types

Prices sell in the order you send them. Buyers choose this ticket on the event page, or you pass its id when creating a checkout session.

Body

namestringrequired
What buyers see, like Weekend pass.
tiersarray of pricesrequired
Its prices in selling order, 1 to 10. Each takes label, price, and optionally capacity and ends_at (fields under Prices).
session_idsarray of idsoptional
The days it gets people in on. Leave out for every day.
descriptionstringoptional
A line shown to buyers.
hiddenbooleanoptional
Hide it from buyers.

Request

curl https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60/ticket_types \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Saturday",
    "session_ids": ["ses_3b8d5f0c2e4a6b91"],
    "tiers": [
      { "label": "Early bird", "price": 2500, "capacity": 200 },
      { "label": "Standard",   "price": 3200 }
    ]
  }'

Response

{ "id": "tt_6e2f8a3b0c4d5e71", "object": "ticket_type", "name": "Saturday", "session_ids": ["ses_3b8d5f0c2e4a6b91"], "...": "" }

Needs the events:write permission on your key.

Get one ticket type

GET/v1/ticket_types/:id

One ticket type and how many have sold.

Request

curl https://api.eventtickets.dev/v1/ticket_types/tt_5d1e7f2a9b3c4d60 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "id": "tt_5d1e7f2a9b3c4d60",
  "object": "ticket_type",
  "event_id": "evt_3f9a1c2b7d4e5f60",
  "name": "General admission",
  "description": null,
  "session_ids": ["ses_2a7c4e9b1d3f5a80"],
  "position": 0,
  "hidden": false,
  "sold": 0,
  "active_tier_id": "tier_8a2b6c4d1e9f3a70"
}

Needs the events:read permission on your key.

Change a ticket type

PATCH/v1/ticket_types/:id

Tickets already sold keep the days they were bought for.

Body

namestringoptional
A new name.
descriptionstringoptional
A new description, or null.
session_idsarray of idsoptional
The days it covers from now on.
hiddenbooleanoptional
Hide it from buyers, or show it again.

Request

curl -X PATCH https://api.eventtickets.dev/v1/ticket_types/tt_5d1e7f2a9b3c4d60 \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Full pass" }'

Response

{ "id": "tt_5d1e7f2a9b3c4d60", "object": "ticket_type", "name": "Full pass", "...": "" }

Needs the events:write permission on your key.

Delete a ticket type

DELETE/v1/ticket_types/:id

Deletes it and its prices. Only works when no tickets of this type exist, and an event keeps at least one; otherwise hide it.

Request

curl -X DELETE https://api.eventtickets.dev/v1/ticket_types/tt_6e2f8a3b0c4d5e71 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{ "id": "tt_6e2f8a3b0c4d5e71", "object": "ticket_type", "deleted": true }

Needs the events:write permission on your key.

Prices (tiers)

The prices of a ticket type, like Early bird then Standard. In the API they're called tiers. Within a ticket type they sell one at a time, in order: when a price sells out or passes its end date, the next takes over by itself. The last one keeps selling until the event's capacity is reached.

List an event's prices

GET/v1/events/:id/tiers

Every price of every ticket type, in selling order within each type. state is one of active (on sale now), upcoming, sold_out or ended.

Request

curl https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60/tiers -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "list",
  "data": [
    {
      "id": "tier_8a2b6c4d1e9f3a70",
      "object": "tier",
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "label": "Early bird",
      "price": 800,
      "currency": "gbp",
      "capacity": 100,
      "sold": 0,
      "state": "active",
      "active": true,
      "ends_at": null,
      "position": 0,
      "hidden": false,
      "ticket_type_id": "tt_5d1e7f2a9b3c4d60",
      "booking_fee": 54,
      "buyer_pays": 854,
      "organiser_receives": 800
    }
  ],
  "has_more": false
}

Needs the events:read permission on your key.

Add a price

POST/v1/events/:id/tiers

Adds a price at the end of its ticket type's line. It starts selling when the one before it sells out or ends.

Body

labelstringrequired
The name buyers see, like Early bird.
ticket_type_ididoptional
Which ticket type this is a price of. Leave out for the event's first ticket type. Can't be changed later.
priceintegerrequired
Price of one ticket in pence. 0 makes it free.
capacityintegeroptional
Most tickets this tier can sell. Leave out for no tier limit.
ends_atdateoptional
When this tier stops selling, even if tickets are left.
hiddenbooleanoptional
Hide it from buyers without deleting it.

Request

curl https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60/tiers \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "label": "Final release", "price": 1500 }'

Response

{ "id": "tier_0c4d8e6f3a1b5c92", "object": "tier", "label": "Final release", "price": 1500, "state": "upcoming", "...": "" }

Needs the events:write permission on your key.

Change a price

PATCH/v1/tiers/:id

Send only what changes. Tickets already sold keep the name and price they were bought at.

Body

labelstringoptional
The name buyers see, like Early bird.
ticket_type_ididoptional
Which ticket type this is a price of. Leave out for the event's first ticket type. Can't be changed later.
priceintegeroptional
Price of one ticket in pence. 0 makes it free.
capacityintegeroptional
Most tickets this tier can sell. Leave out for no tier limit.
ends_atdateoptional
When this tier stops selling, even if tickets are left.
hiddenbooleanoptional
Hide it from buyers without deleting it.

Request

curl -X PATCH https://api.eventtickets.dev/v1/tiers/tier_8a2b6c4d1e9f3a70 \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "capacity": 150 }'

Response

{ "id": "tier_8a2b6c4d1e9f3a70", "object": "tier", "capacity": 150, "...": "" }

Needs the events:write permission on your key.

Delete a price

DELETE/v1/tiers/:id

Only works on a price with no tickets, and a ticket type keeps at least one price. To stop selling a price that has sales, set "hidden": true instead.

Request

curl -X DELETE https://api.eventtickets.dev/v1/tiers/tier_0c4d8e6f3a1b5c92 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{ "id": "tier_0c4d8e6f3a1b5c92", "object": "tier", "deleted": true }

Needs the events:write permission on your key.

Add-ons

Optional extras buyers add at checkout, like parking, merch or a drinks token. We set the price and hold stock while the buyer pays. Ones marked collect_at_door show up for door staff when any ticket on the order is scanned, and staff mark them handed over.

List an event's add-ons

GET/v1/events/:id/addons

In the order buyers see them, with how many have sold.

Request

curl https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60/addons -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "list",
  "data": [
    {
      "id": "add_3c8e1a5f7b2d4e90",
      "object": "addon",
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "name": "Parking",
      "description": "One car, all night",
      "price": 500,
      "currency": "gbp",
      "capacity": 80,
      "sold": 0,
      "max_per_order": 2,
      "collect_at_door": true,
      "position": 0,
      "hidden": false
    }
  ],
  "has_more": false
}

Needs the events:read permission on your key.

Add an add-on

POST/v1/events/:id/addons

Add-ons belong to the order, not to each ticket: two tickets and one parking is one parking, collectable with either ticket. Discount codes don't apply to add-ons. Buyers choose them on the checkout page.

Body

namestringrequired
What buyers see, like Parking.
priceintegerrequired
Price of one in pence. 0 makes it free.
descriptionstringoptional
A short line shown at checkout.
capacityintegeroptional
How many can be sold in total. Leave out for no limit.
max_per_orderintegeroptional
Most one order can have, 1 to 50. Default 10.
collect_at_doorbooleanoptional
Handed over at the door. Default true.
hiddenbooleanoptional
Hide it from buyers.

Request

curl https://api.eventtickets.dev/v1/events/evt_3f9a1c2b7d4e5f60/addons \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Parking", "price": 500, "capacity": 80, "max_per_order": 2 }'

Response

{
  "id": "add_3c8e1a5f7b2d4e90",
  "object": "addon",
  "event_id": "evt_3f9a1c2b7d4e5f60",
  "name": "Parking",
  "description": "One car, all night",
  "price": 500,
  "currency": "gbp",
  "capacity": 80,
  "sold": 0,
  "max_per_order": 2,
  "collect_at_door": true,
  "position": 0,
  "hidden": false
}

Needs the events:write permission on your key.

Get one add-on

GET/v1/addons/:id

One add-on and how many have sold.

Request

curl https://api.eventtickets.dev/v1/addons/add_3c8e1a5f7b2d4e90 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "id": "add_3c8e1a5f7b2d4e90",
  "object": "addon",
  "event_id": "evt_3f9a1c2b7d4e5f60",
  "name": "Parking",
  "description": "One car, all night",
  "price": 500,
  "currency": "gbp",
  "capacity": 80,
  "sold": 0,
  "max_per_order": 2,
  "collect_at_door": true,
  "position": 0,
  "hidden": false
}

Needs the events:read permission on your key.

Change an add-on

PATCH/v1/addons/:id

Orders already placed keep the name and price they were bought at.

Body

…optional
Any field from Add an add-on. Only what you send is changed.

Request

curl -X PATCH https://api.eventtickets.dev/v1/addons/add_3c8e1a5f7b2d4e90 \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "capacity": 100 }'

Response

{ "id": "add_3c8e1a5f7b2d4e90", "object": "addon", "capacity": 100, "...": "" }

Needs the events:write permission on your key.

Delete an add-on

DELETE/v1/addons/:id

Only add-ons nobody has bought can be deleted; hide the others.

Request

curl -X DELETE https://api.eventtickets.dev/v1/addons/add_3c8e1a5f7b2d4e90 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{ "id": "add_3c8e1a5f7b2d4e90", "object": "addon", "deleted": true }

Needs the events:write permission on your key.

Series

A series groups separate events, like a weekly night or a tour, on one page where buyers pick a date. Each event in it keeps its own tickets, capacity, orders and door list.

List series

GET/v1/series

Your series, newest first. List items don't include their events; get one series for those.

Request

curl https://api.eventtickets.dev/v1/series -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "list",
  "data": [
    { "object": "series", "id": "ser_8b4d2f6a1c3e5b70", "name": "Comedy Thursdays", "url": "https://pay.eventtickets.dev/s/ser_8b4d2f6a1c3e5b70", "...": "" }
  ],
  "has_more": false
}

Needs the events:read permission on your key.

Create a series

POST/v1/series

Starts empty. Add events with series_id on Change an event, or make new dates with Copy an event to new dates. Send buyers to its url.

Body

namestringrequired
Shown on the series page.
descriptionstringoptional
Shown on the series page.

Request

curl https://api.eventtickets.dev/v1/series \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Comedy Thursdays" }'

Response

{ "object": "series", "id": "ser_8b4d2f6a1c3e5b70", "name": "Comedy Thursdays", "events": [], "...": "" }

Needs the events:write permission on your key.

Get a series and its dates

GET/v1/series/:id

The series with its events in date order.

Request

curl https://api.eventtickets.dev/v1/series/ser_8b4d2f6a1c3e5b70 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "series",
  "id": "ser_8b4d2f6a1c3e5b70",
  "livemode": false,
  "name": "Comedy Thursdays",
  "slug": "comedy-thursdays",
  "description": null,
  "created_at": "2026-10-04T09:50:00+00:00",
  "url": "https://pay.eventtickets.dev/s/ser_8b4d2f6a1c3e5b70",
  "events": [
    { "id": "evt_3f9a1c2b7d4e5f60", "object": "event", "starts_at": "2026-11-05T19:30:00+00:00", "...": "" },
    { "id": "evt_4a0b2d3c8e5f6a71", "object": "event", "starts_at": "2026-11-12T19:30:00+00:00", "...": "" }
  ]
}

Needs the events:read permission on your key.

Change a series

PATCH/v1/series/:id

Send only what changes.

Body

namestringoptional
A new name.
descriptionstringoptional
A new description, or null.

Request

curl -X PATCH https://api.eventtickets.dev/v1/series/ser_8b4d2f6a1c3e5b70 \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "description": "Stand-up every Thursday at 7:30." }'

Response

{
  "object": "series",
  "id": "ser_8b4d2f6a1c3e5b70",
  "livemode": false,
  "name": "Comedy Thursdays",
  "slug": "comedy-thursdays",
  "description": null,
  "created_at": "2026-10-04T09:50:00+00:00",
  "url": "https://pay.eventtickets.dev/s/ser_8b4d2f6a1c3e5b70",
  "events": [
    { "id": "evt_3f9a1c2b7d4e5f60", "object": "event", "starts_at": "2026-11-05T19:30:00+00:00", "...": "" },
    { "id": "evt_4a0b2d3c8e5f6a71", "object": "event", "starts_at": "2026-11-12T19:30:00+00:00", "...": "" }
  ]
}

Needs the events:write permission on your key.

Delete a series

DELETE/v1/series/:id

Its events are kept, just no longer grouped.

Request

curl -X DELETE https://api.eventtickets.dev/v1/series/ser_8b4d2f6a1c3e5b70 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{ "id": "ser_8b4d2f6a1c3e5b70", "object": "series", "deleted": true }

Needs the events:write permission on your key.

Checkout

A checkout session is one buyer's trip from your Buy button to paid tickets. You create it on your server and send the buyer to its url. We handle the queue, the hold on their tickets, the card form and the ticket email.

Send a buyer to checkout

POST/v1/checkout_sessions

Redirect the buyer to the url in the response. You never send a price: it comes from the ticket type's current price, so it can't be changed in the browser. If the event has add-ons, the buyer picks them on the checkout page; they appear in addons and amount_addons once chosen.

status starts as queued if the on-sale is busy, or open when the buyer's tickets are held for them (until held_until). It becomes complete when they pay, or expired if they don't. The amounts fill in once the buyer enters their details.

Body

event_ididrequired
The event they're buying for. It must be on sale.
quantityintegerrequired
How many tickets, from 1 to the event's max_per_order.
ticket_type_ididoptional
Which ticket type, like a full pass or a day ticket. Required when the event sells more than one; otherwise its only one is used.
success_urlurloptional
Where to send the buyer as soon as their payment is confirmed, instead of our confirmation page. We fill in {ORDER_ID} and {CHECKOUT_SESSION_ID} if you include them. Without it they see our confirmation page, with their tickets and wallet buttons.
cancel_urlurloptional
Where the Back link on checkout goes.
sourcestringoptional
Where the buyer came from, like instagram. Shows in your analytics.
metadataobjectoptional
Up to 20 of your own key-value strings, like your customer id. Copied onto the order and its webhooks.

Request

curl https://api.eventtickets.dev/v1/checkout_sessions \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: basket-4821-1" \
  -d '{
    "event_id": "evt_3f9a1c2b7d4e5f60",
    "ticket_type_id": "tt_5d1e7f2a9b3c4d60",
    "quantity": 2,
    "success_url": "https://yoursite.com/thanks?order={ORDER_ID}",
    "source": "instagram",
    "metadata": { "customer_id": "4821" }
  }'

Response

{
  "id": "cs_4d8e2a6b1c9f7e30",
  "object": "checkout_session",
  "livemode": false,
  "event_id": "evt_3f9a1c2b7d4e5f60",
  "status": "open",
  "quantity": 2,
  "ticket_type_id": "tt_5d1e7f2a9b3c4d60",
  "tier_id": "tier_8a2b6c4d1e9f3a70",
  "tier_label": "Early bird",
  "unit_amount": 800,
  "currency": "gbp",
  "amount_subtotal": null,
  "amount_discount": null,
  "amount_addons": 0,
  "amount_fee": null,
  "amount_total": null,
  "buyer_email": null,
  "buyer_name": null,
  "success_url": "https://yoursite.com/thanks?order={ORDER_ID}",
  "cancel_url": null,
  "held_until": "2026-11-02T19:13:40+00:00",
  "metadata": { "customer_id": "4821" },
  "source": "instagram",
  "addons": [],
  "created_at": "2026-11-02T19:03:40+00:00",
  "url": "https://pay.eventtickets.dev/c/cs_4d8e2a6b1c9f7e30",
  "order_id": null
}

Needs the checkout:write permission on your key.

Check on a checkout

GET/v1/checkout_sessions/:id

When status is complete, order_id tells you which order it made. On your success_url page it's quicker to put {ORDER_ID} in the URL and get the order directly: see After payment. For anything important, rely on the order.paid webhook too.

Request

curl https://api.eventtickets.dev/v1/checkout_sessions/cs_4d8e2a6b1c9f7e30 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{ "id": "cs_4d8e2a6b1c9f7e30", "object": "checkout_session", "status": "complete", "order_id": "ord_9c1e4b7a2d3f5e60", "...": "" }

Needs the checkout:write permission on your key.

Orders

An order is one paid purchase: who bought, what they paid, and the tickets they got. Orders are created by checkout; you can't create them directly.

List orders

GET/v1/orders

Orders newest first, each with its tickets. Handy for exports and for catching up if your webhook endpoint was down.

Query string

event_ididoptional
Only orders for this event.
statusstringoptional
paid or refunded.
emailstringoptional
Only orders from this buyer email.
limitintegeroptional
How many to return, 1 to 100. Default 20.
starting_afteridoptional
For the next page: the id of the last object you received. See API basics › Lists.

Request

curl "https://api.eventtickets.dev/v1/orders?event_id=evt_3f9a1c2b7d4e5f60&limit=50" -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "list",
  "data": [
    { "id": "ord_9c1e4b7a2d3f5e60", "object": "order", "status": "paid", "amount_total": 1708, "tickets": ["..."], "...": "" }
  ],
  "has_more": true
}

Needs the orders:read permission on your key.

Get one order

GET/v1/orders/:id

The amounts add up like this: amount_subtotal − amount_discount + amount_addons + amount_fee (when the buyer pays the fee) = amount_total, which is what the buyer was charged. addons lists the extras bought, and collected shows how many were handed over at the door.

Request

curl https://api.eventtickets.dev/v1/orders/ord_9c1e4b7a2d3f5e60 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "id": "ord_9c1e4b7a2d3f5e60",
  "object": "order",
  "livemode": false,
  "event_id": "evt_3f9a1c2b7d4e5f60",
  "checkout_session_id": "cs_4d8e2a6b1c9f7e30",
  "status": "paid",
  "currency": "gbp",
  "amount_subtotal": 1600,
  "amount_discount": 0,
  "amount_addons": 500,
  "amount_fee": 123,
  "fee_payer": "buyer",
  "amount_total": 2223,
  "buyer_email": "ama@example.com",
  "buyer_name": "Ama Owusu",
  "paid_at": "2026-11-02T19:04:11+00:00",
  "refunded_at": null,
  "metadata": { "customer_id": "4821" },
  "created_at": "2026-11-02T19:04:11+00:00",
  "tickets": [
    {
      "id": "tkt_1b2c3d4e5f607182",
      "object": "ticket",
      "livemode": false,
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "order_id": "ord_9c1e4b7a2d3f5e60",
      "tier_id": "tier_8a2b6c4d1e9f3a70",
      "tier_label": "Early bird",
      "ticket_type_id": "tt_5d1e7f2a9b3c4d60",
      "session_ids": ["ses_2a7c4e9b1d3f5a80"],
      "amount": 800,
      "type": "paid",
      "status": "valid",
      "holder_name": null,
      "holder_email": null,
      "note": null,
      "redeemed_at": null,
      "created_at": "2026-11-02T19:04:11+00:00",
      "url": "https://pay.eventtickets.dev/t/9f2c41e07ab35d18c6e4f0b2a1d97e53",
      "apple_wallet_url": "https://pay.eventtickets.dev/t/9f2c41e07ab35d18c6e4f0b2a1d97e53/wallet/apple",
      "google_wallet_url": "https://pay.eventtickets.dev/t/9f2c41e07ab35d18c6e4f0b2a1d97e53/wallet/google"
    },
    { "id": "tkt_2c3d4e5f60718293", "object": "ticket", "...": "same shape" }
  ],
  "addons": [
    { "object": "order_addon", "id": "oad_7e2a4c6b9d1f3a50", "addon_id": "add_3c8e1a5f7b2d4e90", "name": "Parking", "unit_amount": 500, "quantity": 1, "collect_at_door": true, "collected": 0 }
  ]
}

Needs the orders:read permission on your key.

Refund an order

POST/v1/orders/:id/refund

Gives the buyer all their money back, booking fee included, and cancels the tickets so they no longer scan. The tickets go back on sale. Refunding an order twice does nothing the second time. We send an order.refunded webhook.

Request

curl -X POST https://api.eventtickets.dev/v1/orders/ord_9c1e4b7a2d3f5e60/refund \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Idempotency-Key: refund-ord_9c1e4b7a2d3f5e60"

Response

{ "id": "ord_9c1e4b7a2d3f5e60", "object": "order", "status": "refunded", "refunded_at": "2026-11-05T10:22:03+00:00", "...": "" }

Needs the orders:write permission on your key.

Email the tickets again

POST/v1/orders/:id/resend

For the "I can't find my tickets" email. Sends the order's tickets to the buyer's email address again.

Request

curl -X POST https://api.eventtickets.dev/v1/orders/ord_9c1e4b7a2d3f5e60/resend -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{ "id": "ord_9c1e4b7a2d3f5e60", "object": "order", "...": "" }

Needs the orders:write permission on your key.

Tickets

One ticket gets one person in, on each day in its session_ids. Paid tickets come from orders; guest-list tickets are free and issued by you. Each has a url to its own page with the QR code.

List tickets

GET/v1/tickets

For example, everyone who has checked in so far, or the whole guest list for one night.

Query string

event_ididoptional
Only tickets for this event.
order_ididoptional
Only tickets from this order.
typestringoptional
paid or comp (guest list).
statusstringoptional
valid (not used yet), redeemed (checked in) or void (cancelled).
emailstringoptional
Only guest-list tickets for this email.
limitintegeroptional
How many to return, 1 to 100. Default 20.
starting_afteridoptional
For the next page: the id of the last object you received. See API basics › Lists.

Request

curl "https://api.eventtickets.dev/v1/tickets?event_id=evt_3f9a1c2b7d4e5f60&status=redeemed" -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "list",
  "data": [
    {
      "id": "tkt_1b2c3d4e5f607182",
      "object": "ticket",
      "livemode": false,
      "event_id": "evt_3f9a1c2b7d4e5f60",
      "order_id": "ord_9c1e4b7a2d3f5e60",
      "tier_id": "tier_8a2b6c4d1e9f3a70",
      "tier_label": "Early bird",
      "ticket_type_id": "tt_5d1e7f2a9b3c4d60",
      "session_ids": ["ses_2a7c4e9b1d3f5a80"],
      "amount": 800,
      "type": "paid",
      "status": "valid",
      "holder_name": null,
      "holder_email": null,
      "note": null,
      "redeemed_at": null,
      "created_at": "2026-11-02T19:04:11+00:00",
      "url": "https://pay.eventtickets.dev/t/9f2c41e07ab35d18c6e4f0b2a1d97e53",
      "apple_wallet_url": "https://pay.eventtickets.dev/t/9f2c41e07ab35d18c6e4f0b2a1d97e53/wallet/apple",
      "google_wallet_url": "https://pay.eventtickets.dev/t/9f2c41e07ab35d18c6e4f0b2a1d97e53/wallet/google"
    }
  ],
  "has_more": false
}

Needs the tickets:read permission on your key.

Get one ticket

GET/v1/tickets/:id

redeemed_at is set when it was first scanned in. url is the ticket page with the QR code: treat it like the ticket itself and only share it with the holder.

apple_wallet_url and google_wallet_url add the ticket to Apple Wallet or Google Wallet. Link to them from your own pages with the official badges. Each is null when that wallet is turned off for the event or the ticket is void.

Request

curl https://api.eventtickets.dev/v1/tickets/tkt_1b2c3d4e5f607182 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "id": "tkt_1b2c3d4e5f607182",
  "object": "ticket",
  "livemode": false,
  "event_id": "evt_3f9a1c2b7d4e5f60",
  "order_id": "ord_9c1e4b7a2d3f5e60",
  "tier_id": "tier_8a2b6c4d1e9f3a70",
  "tier_label": "Early bird",
  "ticket_type_id": "tt_5d1e7f2a9b3c4d60",
  "session_ids": ["ses_2a7c4e9b1d3f5a80"],
  "amount": 800,
  "type": "paid",
  "status": "valid",
  "holder_name": null,
  "holder_email": null,
  "note": null,
  "redeemed_at": null,
  "created_at": "2026-11-02T19:04:11+00:00",
  "url": "https://pay.eventtickets.dev/t/9f2c41e07ab35d18c6e4f0b2a1d97e53",
  "apple_wallet_url": "https://pay.eventtickets.dev/t/9f2c41e07ab35d18c6e4f0b2a1d97e53/wallet/apple",
  "google_wallet_url": "https://pay.eventtickets.dev/t/9f2c41e07ab35d18c6e4f0b2a1d97e53/wallet/google"
}

Needs the tickets:read permission on your key.

Issue guest-list tickets

POST/v1/tickets

Free tickets that scan like paid ones. We email them to the holder straight away; emailed tells you if that worked.

Body

event_ididrequired
Which event.
holder_namestringrequired
Who the tickets are for.
holder_emailstringrequired
Where we email them.
quantityintegeroptional
How many, 1 to 20. Default 1.
ticket_type_ididoptional
Give them this ticket type's days, like a Saturday ticket. Without it (or tier_id), the ticket covers every day.
tier_ididoptional
Show a price's name on the ticket. Its ticket type's days apply. Without it, the ticket says Guest list.
notestringoptional
For your team only, like Press or DJ +1.
allow_over_capacitybooleanoptional
Issue even if the event is full. Default false.

Request

curl https://api.eventtickets.dev/v1/tickets \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_id": "evt_3f9a1c2b7d4e5f60",
    "holder_name": "Kofi Mensah",
    "holder_email": "kofi@example.com",
    "quantity": 2,
    "note": "DJ +1"
  }'

Response

{
  "object": "list",
  "data": [
    { "id": "tkt_5e6f708192a3b4c5", "object": "ticket", "type": "comp", "amount": 0, "tier_label": "Guest list", "...": "" },
    { "id": "tkt_6f708192a3b4c5d6", "object": "ticket", "type": "comp", "amount": 0, "tier_label": "Guest list", "...": "" }
  ],
  "has_more": false,
  "emailed": true
}

Needs the tickets:write permission on your key.

Email a ticket again

POST/v1/tickets/:id/resend

Sends one ticket to its holder's email again. For paid orders, resending the order is usually easier.

Request

curl -X POST https://api.eventtickets.dev/v1/tickets/tkt_5e6f708192a3b4c5/resend -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{ "id": "tkt_5e6f708192a3b4c5", "object": "ticket", "...": "" }

Needs the tickets:write permission on your key.

Cancel a guest-list ticket

POST/v1/tickets/:id/void

The ticket stops scanning at once. Paid tickets can't be cancelled this way: refund their order so the buyer gets their money back.

Request

curl -X POST https://api.eventtickets.dev/v1/tickets/tkt_5e6f708192a3b4c5/void -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{ "id": "tkt_5e6f708192a3b4c5", "object": "ticket", "status": "void", "...": "" }

Needs the tickets:write permission on your key.

Discount codes

Codes buyers type at checkout for money off each ticket. A use only counts once the order is paid, so abandoned checkouts don't use up a limited code.

Create a code

POST/v1/coupons

Codes are unique in your account. Once made, the code and discount can't change; turn it off and make a new one instead.

Body

codestringrequired
What buyers type. 3 to 32 letters, numbers, dashes or underscores. Not case sensitive.
discount_typepercent | fixedrequired
Take a percentage off, or a fixed amount off each ticket.
discount_valueintegerrequired
For percent, 1 to 100. For fixed, pence off each ticket (250 is £2.50).
event_ididoptional
Only for this event. Leave out for every event.
labelstringoptional
A note for your team, like Student rate.
max_usesintegeroptional
How many orders can use it. Leave out for no limit.
require_email_domainstringoptional
Only buyers whose email ends in this, like ac.uk for students.
expires_atdateoptional
When it stops working.

Request

curl https://api.eventtickets.dev/v1/coupons \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "STUDENT25",
    "label": "Student rate",
    "discount_type": "percent",
    "discount_value": 25,
    "max_uses": 200,
    "require_email_domain": "ac.uk"
  }'

Response

{
  "id": "cpn_6e2f8a4c1b3d9e50",
  "object": "coupon",
  "livemode": false,
  "event_id": null,
  "code": "STUDENT25",
  "label": "Student rate",
  "discount_type": "percent",
  "discount_value": 25,
  "require_email_domain": "ac.uk",
  "max_uses": 200,
  "used_count": 0,
  "active": true,
  "expires_at": null,
  "created_at": "2026-10-04T09:30:00+00:00"
}

Needs the coupons:write permission on your key.

List codes

GET/v1/coupons

All your codes, newest first, with how many times each has been used.

Query string

limitintegeroptional
How many to return, 1 to 100. Default 20.
starting_afteridoptional
For the next page: the id of the last object you received. See API basics › Lists.

Request

curl https://api.eventtickets.dev/v1/coupons -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "list",
  "data": [
    {
      "id": "cpn_6e2f8a4c1b3d9e50",
      "object": "coupon",
      "livemode": false,
      "event_id": null,
      "code": "STUDENT25",
      "label": "Student rate",
      "discount_type": "percent",
      "discount_value": 25,
      "require_email_domain": "ac.uk",
      "max_uses": 200,
      "used_count": 0,
      "active": true,
      "expires_at": null,
      "created_at": "2026-10-04T09:30:00+00:00"
    }
  ],
  "has_more": false
}

Needs the coupons:read permission on your key.

Get one code

GET/v1/coupons/:id

One code and its usage so far.

Request

curl https://api.eventtickets.dev/v1/coupons/cpn_6e2f8a4c1b3d9e50 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "id": "cpn_6e2f8a4c1b3d9e50",
  "object": "coupon",
  "livemode": false,
  "event_id": null,
  "code": "STUDENT25",
  "label": "Student rate",
  "discount_type": "percent",
  "discount_value": 25,
  "require_email_domain": "ac.uk",
  "max_uses": 200,
  "used_count": 0,
  "active": true,
  "expires_at": null,
  "created_at": "2026-10-04T09:30:00+00:00"
}

Needs the coupons:read permission on your key.

Change or turn off a code

PATCH/v1/coupons/:id

Send only what changes.

Body

activebooleanoptional
false turns the code off straight away; true turns it back on.
max_usesintegeroptional
A new limit. It can't be lower than the uses so far.
expires_atdateoptional
A new end date, or null for none.
labelstringoptional
A new note for your team.

Request

curl -X PATCH https://api.eventtickets.dev/v1/coupons/cpn_6e2f8a4c1b3d9e50 \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "active": false }'

Response

{ "id": "cpn_6e2f8a4c1b3d9e50", "object": "coupon", "active": false, "...": "" }

Needs the coupons:write permission on your key.

Check a code without using it

POST/v1/coupons/preview

For showing "£9.00 with your code" on your own site before checkout. If the code can't be used you get "valid": false and a reason written for the buyer, like "That code has expired." The buyer still enters the code at checkout.

Body

event_ididrequired
The event the buyer wants.
codestringrequired
What the buyer typed.
emailstringrequired
The buyer's email, for codes limited to an email domain.
tier_ididoptional
Include it to get the price before and after the discount.

Request

curl https://api.eventtickets.dev/v1/coupons/preview \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_id": "evt_3f9a1c2b7d4e5f60",
    "code": "student25",
    "email": "sam@bristol.ac.uk",
    "tier_id": "tier_9b3c7d5e2f0a4b81"
  }'

Response

{
  "object": "coupon_preview",
  "valid": true,
  "coupon": { "id": "cpn_6e2f8a4c1b3d9e50", "code": "STUDENT25", "...": "" },
  "unit_amount": 1200,
  "unit_amount_after_discount": 900
}

Needs the coupons:read permission on your key.

Webhook endpoints

The URLs on your server we send events to. Most people add these in the dashboard; these endpoints are for setting them up from code. How webhooks work is on the Webhooks page.

Add an endpoint

POST/v1/webhook_endpoints

The response includes secret, used to check each webhook really came from us. Store it now: the API never returns it again (you can still reveal it in the dashboard). Up to 10 endpoints in each mode.

Body

urlurlrequired
Where to send events. Live endpoints need a public https:// address.
eventsarray of stringsrequired
Which events to send, like ["order.paid"]. ["*"] means all of them.
descriptionstringoptional
A note for your team.

Request

curl https://api.eventtickets.dev/v1/webhook_endpoints \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://yoursite.com/webhooks/eventtickets",
    "events": ["order.paid", "order.refunded"],
    "description": "Website orders"
  }'

Response

{
    "id": "we_7f3a9c1e5b2d4a80",
  "object": "webhook_endpoint",
  "livemode": false,
  "url": "https://yoursite.com/webhooks/eventtickets",
  "description": "Website orders",
  "events": ["order.paid", "order.refunded"],
  "created_at": "2026-10-04T09:40:00+00:00",
  "disabled": false,
  "secret": "whsec_Qm9yZ2V0IHRoaXMgaXMgYW4gZXhhbXBsZQ"
}

Needs the webhooks:write permission on your key.

List endpoints

GET/v1/webhook_endpoints

Your endpoints in this mode, without their secrets.

Query string

limitintegeroptional
How many to return, 1 to 100. Default 20.
starting_afteridoptional
For the next page: the id of the last object you received. See API basics › Lists.

Request

curl https://api.eventtickets.dev/v1/webhook_endpoints -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "list",
  "data": [
    {
      "id": "we_7f3a9c1e5b2d4a80",
      "object": "webhook_endpoint",
      "livemode": false,
      "url": "https://yoursite.com/webhooks/eventtickets",
      "description": "Website orders",
      "events": ["order.paid", "order.refunded"],
      "created_at": "2026-10-04T09:40:00+00:00",
      "disabled": false
    }
  ],
  "has_more": false
}

Needs the webhooks:read permission on your key.

Get one endpoint

GET/v1/webhook_endpoints/:id

One endpoint and the events it receives.

Request

curl https://api.eventtickets.dev/v1/webhook_endpoints/we_7f3a9c1e5b2d4a80 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "id": "we_7f3a9c1e5b2d4a80",
  "object": "webhook_endpoint",
  "livemode": false,
  "url": "https://yoursite.com/webhooks/eventtickets",
  "description": "Website orders",
  "events": ["order.paid", "order.refunded"],
  "created_at": "2026-10-04T09:40:00+00:00",
  "disabled": false
}

Needs the webhooks:read permission on your key.

Delete an endpoint

DELETE/v1/webhook_endpoints/:id

Stops all deliveries to this URL, including any waiting to be retried.

Request

curl -X DELETE https://api.eventtickets.dev/v1/webhook_endpoints/we_7f3a9c1e5b2d4a80 -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{ "id": "we_7f3a9c1e5b2d4a80", "object": "webhook_endpoint", "deleted": true }

Needs the webhooks:write permission on your key.

Branding

How your event pages, checkout, confirmation page, tickets and ticket emails look and read to buyers. The same settings as Settings › Customisation in the dashboard. Branding belongs to your organisation, so test and live keys see and change the same settings.

Get your branding

GET/v1/branding

Every setting is listed. null means you're using ours: our lime accent, or our wording. Upload your logo in the dashboard; logo_url is read-only here.

Request

curl https://api.eventtickets.dev/v1/branding -H "Authorization: Bearer $EVENTTICKETS_KEY"

Response

{
  "object": "branding",
  "name": "Harbour Nights",
  "logo_url": null,
  "support_email": "hello@harbournights.com",
  "email_theme": "light",
  "email_accent": null,
  "checkout": {
    "theme": "dark",
    "accent": "#1D4ED8",
    "show_name": true,
    "text": {
      "checkout_message": "All sales are final. Doors open at 10pm.",
      "details_button": null,
      "pay_button": "Buy now for {amount}",
      "terms_url": "https://harbournights.com/terms",
      "confirmation_heading": "See you on the dance floor.",
      "confirmation_message": null,
      "confirmation_button_label": null,
      "confirmation_button_url": null
    }
  }
}

Needs the branding:read permission on your key.

Change colours and wording

PATCH/v1/branding

Send only what you want to change. Inside checkout.text, only the keys you send change, and null puts one back to our wording. Buyers see changes straight away, including anyone already on checkout when they next load a page.

Our "Ticketing by EventTickets" badge isn't a setting: it shows on every page in your colours.

Body

checkout.themestringoptional
light or dark. Applies to your event, series, checkout, confirmation and ticket pages.
checkout.accentstringoptional
Colour for main buttons and highlights, like #1D4ED8. Text on it switches between dark and light to stay readable. null for our lime.
checkout.show_namebooleanoptional
Show your organisation name next to your logo. Set false if your logo includes it.
checkout.text.checkout_messagestringoptional
A note under the event name on checkout, up to 500 characters. Line breaks are kept.
checkout.text.details_buttonstringoptional
The button after the buyer's details. Ours: Continue to payment. Up to 40 characters.
checkout.text.pay_buttonstringoptional
The card step button. {amount} becomes the total. Ours: Pay {amount}. Up to 40 characters.
checkout.text.terms_urlurloptional
Adds a line under the buttons saying buyers agree to your terms and conditions, linked here.
checkout.text.confirmation_headingstringoptional
The confirmation page heading. Ours: You're in. Up to 60 characters.
checkout.text.confirmation_messagestringoptional
A note under the buyer's tickets on the confirmation page, up to 500 characters.
checkout.text.confirmation_button_labelstringoptional
Adds a button to the confirmation page, like Join our mailing list. Set it with confirmation_button_url.
checkout.text.confirmation_button_urlurloptional
Where that button goes.
support_emailstringoptional
Contact email shown to buyers on your pages and emails. null hides it.
email_themestringoptional
light or dark, for ticket emails.
email_accentstringoptional
Ticket email and wallet pass colour, like #1D4ED8. null for our lime.

Request

curl -X PATCH https://api.eventtickets.dev/v1/branding \
  -H "Authorization: Bearer $EVENTTICKETS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "checkout": {
      "theme": "dark",
      "accent": "#1D4ED8",
      "text": {
        "pay_button": "Buy now for {amount}",
        "confirmation_heading": "See you on the dance floor."
      }
    }
  }'

Response

{
  "object": "branding",
  "name": "Harbour Nights",
  "logo_url": null,
  "support_email": "hello@harbournights.com",
  "email_theme": "light",
  "email_accent": null,
  "checkout": {
    "theme": "dark",
    "accent": "#1D4ED8",
    "show_name": true,
    "text": {
      "checkout_message": "All sales are final. Doors open at 10pm.",
      "details_button": null,
      "pay_button": "Buy now for {amount}",
      "terms_url": "https://harbournights.com/terms",
      "confirmation_heading": "See you on the dance floor.",
      "confirmation_message": null,
      "confirmation_button_label": null,
      "confirmation_button_url": null
    }
  }
}

Needs the branding:write permission on your key.

Stuck? Every error message says what went wrong and usually how to fix it. See API basics › Errors for the full list of error codes.