RU
Docs sections

Events

An event is a date, a venue and tiers. Create it as a draft, publish it, and sales open.

A new event starts as a draft (draft). You can change a draft any way you like, but you can't sell tickets for it. Publishing (published) opens sales, and after that the tiers no longer change.

Event object

FieldTypeDescription
idstringEvent UUID
org_idstringOrganization UUID
livemodebooleantrue for a live event, false for a test one
titlestringTitle, up to 200 characters
starts_at, ends_atstringStart and end, RFC 3339 in UTC
timezonestringIANA time zone, such as Europe/Moscow. The email and the ticket show times in it
venue_name, venue_addressstringVenue and address, up to 300 characters
statusstringdraft (draft) or published (on sale)
tariffsarrayTiers, see below
has_seatsbooleanThe event has a tier with seats
ticket_stylestringTicket look: ticket (a white ticket with a tear-off line) or pass (a pass with a lime header)
coverstringCover version. An empty string means no cover

Tier

FieldTypeDescription
idstringTier UUID. You pass it in an order
codestringCode: Latin letters, digits, _ and -, up to 32 characters. Unique within the event. Defaults to t1, t2…
namestringName, up to 100 characters. Never repeats within the event, case-insensitive
price_minorstringPrice in kopecks. A number or a string in requests, a string in responses
currencystringThree-letter currency code, RUB by default
quotaintegerHow many tickets to sell, 1 to 1,000,000. For a tier with seats it equals the number of seats
per_order_limitintegerHow many tickets of the tier fit in one order. 0 means no limit
seatedbooleanA tier with seats, see assigned seating
seatsintegerResponse only: how many seats the tier has

Create an event

POST/v1/events

FieldTypeRequiredDescription
titlestringyesTitle
starts_atstringyesStart, RFC 3339
ends_atstringyesEnd, later than the start
timezonestringyesIANA time zone
venue_namestringnoVenue
venue_addressstringnoAddress, the guest gets directions to it
ticket_stylestringnoticket (default) or pass
tariffsarraynoTiers: code, name, price_minor, currency, quota, per_order_limit, seated. A draft doesn't need tiers, publishing needs at least one

Request

curl https://api.budu.events/v1/events \
  -H "Authorization: Bearer $BUDU_KEY" \
  -H "Idempotency-Key: event-jazz-2026" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Джаз в саду",
    "starts_at": "2026-12-12T16:00:00Z",
    "ends_at": "2026-12-12T19:00:00Z",
    "timezone": "Europe/Moscow",
    "venue_name": "Площадка «Сад»",
    "venue_address": "Москва, Садовая улица, 1",
    "ticket_style": "ticket",
    "tariffs": [
      {
        "code": "dance",
        "name": "Танцпол",
        "price_minor": 250000,
        "quota": 300,
        "per_order_limit": 6
      }
    ]
  }'

Response 201

{
  "id": "0193e0b2-4a7c-7d10-9e3f-2c5a8b1d4e60",
  "org_id": "0193d9a1-2b3c-7d4e-8f50-61728394a5b6",
  "livemode": false,
  "title": "Джаз в саду",
  "starts_at": "2026-12-12T16:00:00Z",
  "ends_at": "2026-12-12T19:00:00Z",
  "timezone": "Europe/Moscow",
  "venue_name": "Площадка «Сад»",
  "venue_address": "Москва, Садовая улица, 1",
  "status": "draft",
  "tariffs": [
    {
      "id": "0193e0b2-4a7d-7a21-8c44-6e2f9a0b3c71",
      "code": "dance",
      "name": "Танцпол",
      "price_minor": "250000",
      "currency": "RUB",
      "quota": 300,
      "per_order_limit": 6,
      "seated": false,
      "seats": 0
    }
  ],
  "has_seats": false,
  "ticket_style": "ticket",
  "cover": ""
}

Errors: 400 invalid_request with the reason in message. For example: no title, the end before the start, an unknown time zone, a repeated tier code or name, a quota out of range. If a tier is at fault, its code is in details.code.

List events

GET/v1/events

Every event of the organization in the key's mode, by start time.

Request

curl https://api.budu.events/v1/events -H "Authorization: Bearer $BUDU_KEY"

You get 200 with {"events": [...]}, each event an event object with every field.

Get an event

GET/v1/events/{id}

Request

curl https://api.budu.events/v1/events/0193e0b2-4a7c-7d10-9e3f-2c5a8b1d4e60 \
  -H "Authorization: Bearer $BUDU_KEY"

You get 200 with the event object. Another organization's event or an event of the other mode gives 404 not_found.

Update an event

PATCH/v1/events/{id}

Only the fields you send change, the rest stay as they were. You can send title, starts_at, ends_at, timezone, venue_name, venue_address, ticket_style and tariffs. Any other field gives 400 invalid_request with the field name in details.field.

  • tariffs replaces the draft's tiers as a whole. To keep a tier, pass its id. A tier without an id is new, and a tier missing from the list is deleted together with its seats.
  • A published event's tiers don't change: 400 invalid_request. You can still change the title, times, venue and ticket look.

Request

curl -X PATCH https://api.budu.events/v1/events/0193e0b2-4a7c-7d10-9e3f-2c5a8b1d4e60 \
  -H "Authorization: Bearer $BUDU_KEY" \
  -H "Content-Type: application/json" \
  -d '{"venue_name": "Летняя сцена", "ticket_style": "pass"}'

You get 200 with the updated event.

Publish

POST/v1/events/{id}/publish

Opens sales. You need at least one tier, and tiers with seats need their seats uploaded.

Request

curl -X POST https://api.budu.events/v1/events/0193e0b2-4a7c-7d10-9e3f-2c5a8b1d4e60/publish \
  -H "Authorization: Bearer $BUDU_KEY"

You get 200 with the event in published status. Stock reaches sales within a few seconds. Until then an order gets 409 event_not_on_sale. Publishing again breaks nothing and answers the same.

Errors: 400 invalid_request: «Добавьте хотя бы один тариф» (add at least one tier), «Загрузите места для тарифа «…»» (upload the seats for the tier, details.tariff_id).

Availability

GET/v1/events/{id}/availability

How many tickets are left in each tier. Handy for showing "12 left" on your site or closing sales of a tier.

ParameterDescription
seats1: add seat states
seats_afterid of the last seat on the previous page
seats_limitSeats per page, 1 to 5,000
sectorOnly the seats of this sector

Request

curl https://api.budu.events/v1/events/0193e0b2-4a7c-7d10-9e3f-2c5a8b1d4e60/availability \
  -H "Authorization: Bearer $BUDU_KEY"

Response 200

{
  "tariffs": [
    {
      "tariff_id": "0193e0b2-4a7d-7a21-8c44-6e2f9a0b3c71",
      "quota": 300,
      "sold": 212,
      "available": 79,
      "held": 9,
      "seated": false
    }
  ],
  "seats": [],
  "seats_last": false
}

held counts tickets in active reservations: nobody has paid for them yet. available = quota − sold − held. Seat states are described in assigned seating.

Cover

PUT/v1/events/{id}/cover

The event's picture. The guest sees it as a band across the top of the ticket, on the page and in the email. The request body is the picture itself, not a form.

Request

curl -X PUT https://api.budu.events/v1/events/0193e0b2-4a7c-7d10-9e3f-2c5a8b1d4e60/cover \
  -H "Authorization: Bearer $BUDU_KEY" \
  -H "Content-Type: image/jpeg" \
  --data-binary @cover.jpg
  • JPEG, PNG or WebP. We check the format by the file's content, not by the header.
  • Up to 5 MB and 25 megapixels, at least 640 px wide, landscape: 3:2 to 2:1. 16:9 works best, such as 1920×1080.
  • The ticket shows the cover at 16:9: a 3:2 picture loses its top and bottom edges. Keep text and faces near the center.
  • We store our own copy: a JPEG up to 1,200 px wide with no metadata. A transparent PNG background turns white.
  • You can change the cover in any event status. The ticket page shows the new one right away, emails already sent keep the old one.

You get 200 with the event, with the new version in cover. Errors: 400 invalid_request with the reason in message. If the proportions or the size don't fit, details holds width and height.

DELETE/v1/events/{id}/cover

Removes the cover. You get 200 with the event, cover empty.