# Quickstart

From a test key to a QR ticket in five minutes. Everything runs in test mode, so real sales and guests never see these requests.

Your site sells a ticket and takes the payment. After payment it sends the order to the budu API. We issue QR tickets, email the guest a link to the ticket and check the QR at the door.

- Base URL: `https://api.budu.events/v1`, HTTPS only.
- Requests and responses are JSON, encoded as UTF-8.
- The key goes in the `Authorization: Bearer bt_test_…` header.

## Get a test key {#key}

The organization owner creates keys in the dashboard under **интеграция → ключи API** (Integration → API keys). Switch the dashboard to test mode and the key comes out as a test key, prefixed `bt_test_`. You see the full key once, so save it right away.

```bash
export BUDU_KEY=bt_test_…
```

A test key sees test events only. Emails for test orders go to the organization's staff addresses and to the addresses under **настройки → тестовые адресаты** (Settings → Test recipients). Add your own address there to receive the ticket email. More in [test mode](https://budu.events/en/docs/test-mode/).

## Create an event {#event}

A new event starts as a draft. Send times in UTC as RFC 3339; the email and the ticket page use the time zone. `price_minor` is the price in kopecks: `250000` means 2,500 ₽.

```bash 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",
    "tariffs": [
      {"code": "dance", "name": "Танцпол", "price_minor": 250000, "quota": 300}
    ]
  }'
```

The response holds the whole event. You need the event `id` and the tier `id` next:

```json Response 201
{
  "id": "0193e0b2-4a7c-7d10-9e3f-2c5a8b1d4e60",
  "title": "Джаз в саду",
  "status": "draft",
  "tariffs": [
    {
      "id": "0193e0b2-4a7d-7a21-8c44-6e2f9a0b3c71",
      "code": "dance",
      "name": "Танцпол",
      "price_minor": "250000",
      "currency": "RUB",
      "quota": 300
    }
  ]
}
```

## Publish the event {#publish}

Sales open only for a published event.

```bash 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. An order sent before that gets `409 event_not_on_sale`: retry it a little later or check [availability](https://budu.events/en/docs/events/#availability).

## Send an order {#order}

Your site sends this request after payment. Put your own order number in `Idempotency-Key`. If the response gets lost, a retry with the same key returns the same order and no second set of tickets is issued.

```bash Request
curl https://api.budu.events/v1/orders \
  -H "Authorization: Bearer $BUDU_KEY" \
  -H "Idempotency-Key: order-1042" \
  -H "Content-Type: application/json" \
  -d '{
    "event_id": "0193e0b2-4a7c-7d10-9e3f-2c5a8b1d4e60",
    "items": [{"tariff_id": "0193e0b2-4a7d-7a21-8c44-6e2f9a0b3c71", "qty": 2}],
    "buyer": {
      "email": "maria@example.ru",
      "first_name": "Мария",
      "last_name": "Соколова"
    },
    "payment_ref": "pay-77812"
  }'
```

```json Response 201
{
  "id": "0193e0c5-1f20-7c3e-b6a1-9d4e2f7a8b10",
  "org_id": "0193d9a1-2b3c-7d4e-8f50-61728394a5b6",
  "livemode": false,
  "event_id": "0193e0b2-4a7c-7d10-9e3f-2c5a8b1d4e60",
  "status": "issued",
  "buyer": {
    "email": "maria@example.ru",
    "first_name": "Мария",
    "last_name": "Соколова",
    "phone": ""
  },
  "items": [
    {"tariff_id": "0193e0b2-4a7d-7a21-8c44-6e2f9a0b3c71", "qty": 2, "seat": ""}
  ],
  "hold_expires_at": "2026-10-22T12:15:04Z",
  "payment_ref": "pay-77812",
  "tickets": [
    {
      "id": "0193e0c5-1f6b-7e02-a3c9-5b8d1e4f9f0a",
      "url": "https://budu.events/t/Vw3kqP7nX2bLmR9tYc4sHa",
      "tariff_id": "0193e0b2-4a7d-7a21-8c44-6e2f9a0b3c71",
      "holder_first_name": "Мария",
      "holder_last_name": "Соколова",
      "status": "valid",
      "seat": null
    },
    {
      "id": "0193e0c5-1f6b-7e02-a3c9-5b8d1e4fa21c",
      "url": "https://budu.events/t/9pLmZ2xQw8RkT4vNb6CyJe",
      "tariff_id": "0193e0b2-4a7d-7a21-8c44-6e2f9a0b3c71",
      "holder_first_name": "Мария",
      "holder_last_name": "Соколова",
      "status": "valid",
      "seat": null
    }
  ],
  "seats": [],
  "reason": "",
  "source": "api"
}
```

## Open the ticket {#ticket}

`tickets[].url` leads to the ticket page with the QR. You can show this link to the buyer on your site right after payment. A test ticket carries a "ТЕСТ" (TEST) banner. If your address is among the test recipients, the ticket email arrives in your inbox too.

Sometimes tickets take longer than a couple of seconds to issue. Then the response is `202` with `{"status": "processing", "order_id": "…"}`. The tickets get issued on their own and the email goes out as usual. The links appear in [`GET /v1/orders/{id}`](https://budu.events/en/docs/orders/#get).

## What's next {#next}

- [Keys and requests](https://budu.events/en/docs/auth/): the live key and field formats.
- [Idempotency](https://budu.events/en/docs/idempotency/): how to retry requests safely.
- [Errors and limits](https://budu.events/en/docs/errors/): error codes and what to do about them.
- [Orders](https://budu.events/en/docs/orders/): holding tickets during payment, seats, statuses.
- [Tickets](https://budu.events/en/docs/tickets/): search, cancel, reissue and resend the email.
