Browse API docs

Ticket upgrades

A ticket upgrade pairs one of an event’s tickets with a more expensive one, for example Regular with Fastlane. In the checkout, buyers holding the cheaper ticket see “+4 € Fastlane” beside it and switch with one tap. The offer is never preselected, and both stay ordinary tickets.

Ticket upgrades are optional and off by default. An owner or manager activates them once for the account. Upgrades can be created before that; the checkout offers them once ticket upgrades are activated.

Use a Bearer token and Accept: application/json; the URLs are the dashboard’s. Reading needs Read or Read + Write, every change needs Read + Write. See Authentication. Personal co-organizer tokens manage the upgrades of their assigned events but cannot change the activation.

Fees

On the standard per-ticket plan, Usetix charges the organizer 0.30 in the account’s currency before VAT for each ticket a buyer switches to through an upgrade (EUR 0.30 for euro accounts). It comes on top of the usual fee per sold ticket. Accounts with a percentage fee or no fee pay none, and Usetix can agree individual terms. The activation shows the account’s fee before it is accepted.

  • The fee is paid from Usetix Credit and charged when the order is paid. Usetix Credit must be active to activate ticket upgrades, and the checkout offers an upgrade only while the credit covers its fee.
  • Buyers never see or pay the fee, even when the account passes the Usetix ticket fee on to them. They pay only the price difference of the two tickets; the offer shows the exact extra amount, including any checkout fees the organizer passes on.
  • The fee appears in the Credit usage and as its own line on the monthly Usetix invoice, already paid through credit. results.fees shows what each upgrade’s purchases cost.

Activation

The activation is account-wide. Owners and managers activate and deactivate ticket upgrades, in the dashboard under Settings → Checkout or on an event’s Upgrades tab. External co-organizers and Usetix support cannot: personal co-organizer tokens receive 403 Forbidden on these endpoints.

GET /admin/account_settings/ticket_upgrade_activation

curl -H "Authorization: Bearer your-token-here" \
  -H "Accept: application/json" \
  https://app.usetix.io/admin/account_settings/ticket_upgrade_activation

Response:

{
  "activated": true,
  "activated_at": "2026-10-19T12:00:00Z",
  "fee": { "amount": "0.30", "currency": "EUR" },
  "credit_ready": true
}
Field Type Notes
activated boolean Whether ticket upgrades are activated for the account.
activated_at ISO 8601 or null When they were activated; null while not activated.
fee money or null The fee per switched ticket before VAT. null when the account’s plan has none (percentage or no-fee plans).
credit_ready boolean Whether Usetix Credit is active and covers at least one fee. Always true when there is no fee.

POST /admin/account_settings/ticket_upgrade_activation

Activates ticket upgrades and accepts the fee in fee. Every active upgrade of every event can be offered from then on.

curl -X POST \
  -H "Authorization: Bearer your-token-here" \
  -H "Accept: application/json" \
  https://app.usetix.io/admin/account_settings/ticket_upgrade_activation

Response: 200 OK with the activation in the same shape as GET. When a fee applies and Usetix Credit isn’t active, the response is 422:

{
  "errors": {
    "base": ["…"]
  }
}

Personal co-organizer tokens receive 403 Forbidden.

DELETE /admin/account_settings/ticket_upgrade_activation

Deactivates ticket upgrades. Every offer stops at once; the upgrades stay saved with their results and are offered again after a new activation.

curl -X DELETE \
  -H "Authorization: Bearer your-token-here" \
  -H "Accept: application/json" \
  https://app.usetix.io/admin/account_settings/ticket_upgrade_activation

Response: 200 OK with the activation, now with "activated": false and "activated_at": null. Personal co-organizer tokens receive 403 Forbidden.

Upgrades of an event

:slug is the event’s slug. The rules for a pair:

  • Both tickets belong to the event.
  • Both are single admissions without a seat or area choice. Group tickets and seated tickets take no part.
  • The more expensive ticket (to_ticket) is public and costs more than the cheaper one (from_ticket).
  • A ticket has at most one upgrade.

GET /admin/events/:slug/ticket_upgrades

Lists the event’s upgrades and the pairs Usetix suggests: for a ticket without an upgrade, the next more expensive ticket that offers more and is sold at the same time.

curl -H "Authorization: Bearer your-token-here" \
  -H "Accept: application/json" \
  https://app.usetix.io/admin/events/spring-showcase/ticket_upgrades

Response:

{
  "ticket_upgrades": [
    {
      "id": 7,
      "from_ticket": { "id": 11, "title": "Regular" },
      "to_ticket": { "id": 12, "title": "Fastlane" },
      "price_difference": { "amount": "4.00", "currency": "EUR" },
      "benefit": "No queue at the door",
      "benefit_shown": "No queue at the door",
      "layout": "card",
      "active": true,
      "on_offer": true,
      "unavailable_reason": null,
      "results": {
        "shown": 120,
        "clicks": 31,
        "click_rate": 26,
        "purchases": 12,
        "purchase_rate": 10,
        "tickets_upgraded": 15,
        "revenue": { "amount": "60.00", "currency": "EUR" },
        "fees": { "amount": "4.50", "currency": "EUR" }
      },
      "created_at": "2026-10-19T12:00:00Z",
      "updated_at": "2026-10-19T12:00:00Z"
    }
  ],
  "suggestions": [
    {
      "from_ticket": { "id": 12, "title": "Fastlane" },
      "to_ticket": { "id": 13, "title": "VIP" },
      "price_difference": { "amount": "26.00", "currency": "EUR" },
      "benefit_shown": "Own entrance"
    }
  ]
}

Each item in ticket_upgrades has the ticket upgrade fields. A suggestion has from_ticket, to_ticket, price_difference and benefit_shown in the same form.

POST /admin/events/:slug/ticket_upgrades

Offers to_ticket_id as the upgrade for from_ticket_id.

curl -X POST \
  -H "Authorization: Bearer your-token-here" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"ticket_upgrade": {"from_ticket_id": 11, "to_ticket_id": 12, "benefit": "No queue at the door", "layout": "card"}}' \
  https://app.usetix.io/admin/events/spring-showcase/ticket_upgrades

Body parameters (inside ticket_upgrade; the same fields at the top level of the body work too):

Field Required Notes
from_ticket_id yes The cheaper ticket buyers hold.
to_ticket_id yes The more expensive ticket offered as the upgrade.
benefit no One line on what the buyer gets, up to 60 characters.
layout no card (default), compact, spotlight or compare.

Response: 201 Created with the ticket upgrade and a Location header. A pair that breaks a rule returns 422:

{
  "errors": {
    "to_ticket": ["must cost more than the other ticket"]
  }
}

PATCH /admin/events/:slug/ticket_upgrades/:id

Changes the benefit line or the layout. An empty benefit removes the line. The ticket pair can’t change; to offer another ticket, delete the upgrade and create a new one.

curl -X PATCH \
  -H "Authorization: Bearer your-token-here" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"ticket_upgrade": {"benefit": "Straight in, no queue", "layout": "compare"}}' \
  https://app.usetix.io/admin/events/spring-showcase/ticket_upgrades/7

Response: 200 OK with the updated ticket upgrade. Validation failures return 422 with errors.

POST /admin/events/:slug/ticket_upgrades/:id/pause

Pauses the upgrade: buyers no longer see it and active becomes false. DELETE on the same URL resumes it.

curl -X POST \
  -H "Authorization: Bearer your-token-here" \
  -H "Accept: application/json" \
  https://app.usetix.io/admin/events/spring-showcase/ticket_upgrades/7/pause

Response: 200 OK with the ticket upgrade, for pausing and for resuming.

DELETE /admin/events/:slug/ticket_upgrades/:id

Deletes the upgrade. Its results are deleted too.

curl -X DELETE \
  -H "Authorization: Bearer your-token-here" \
  -H "Accept: application/json" \
  https://app.usetix.io/admin/events/spring-showcase/ticket_upgrades/7

Response: 204 No Content.

Ticket upgrade fields

Field Type Notes
id integer  
from_ticket object id and title of the cheaper ticket.
to_ticket object id and title of the more expensive ticket.
price_difference money The difference of the two ticket prices. The buyer’s offer shows the exact extra amount, including passed-on checkout fees and discounts.
benefit string or null The organizer’s optional line, up to 60 characters.
benefit_shown string or null What the checkout shows: the benefit, or else the more expensive ticket’s features the cheaper one lacks.
layout string card (a row with a switch, the default), compact (one slim “+ Add” line), spotlight (a product card with one wide button) or compare (both tickets side by side).
active boolean false while paused.
on_offer boolean Whether buyers see it right now.
unavailable_reason string or null Why an active upgrade is not on offer; null otherwise. See below.
results object How the upgrade does. See below.
created_at, updated_at ISO 8601  

unavailable_reason is one of:

Value Meaning
not_activated Ticket upgrades aren’t activated for the account.
credit_insufficient Usetix Credit doesn’t cover the fee.
not_upgradeable One of the tickets no longer meets the rules for a pair.
to_ticket_not_public The more expensive ticket is hidden.
not_dearer The more expensive ticket no longer costs more.
not_on_sale The more expensive ticket isn’t on sale.
sold_out The more expensive ticket is sold out.

results counts carts, never people:

Field Notes
shown Carts that saw the offer.
clicks Carts that switched.
click_rate clicks in percent of shown; null before anything was shown.
purchases Paid orders that kept switched tickets.
purchase_rate purchases in percent of shown; null before anything was shown.
tickets_upgraded Tickets switched in those orders.
revenue The extra ticket revenue (money).
fees What Usetix charged from Usetix Credit for them (money).