Штрихкоды и вход
Два сценария контроля входа, и они не заменяют друг друга: онлайн — турникет спрашивает нас в момент прохода; офлайн — коды заранее выгружаются в автономный сканер, а отметки заливаются потом. Офлайн нужен потому, что связь на площадке пропадает именно тогда, когда идёт основной поток людей.
Выгрузка кодов
GET https://api.ctickets.ru/v1/events/145/barcodes?per_page=1000&filter.status=active
Право: barcodes:read.
{
"data": [{
"ticket_id": 14906,
"number": "TKT-20260803-DRUNGVWP",
"barcode": "337069260809",
"status": "active",
"category": { "id": 423, "name": "Партер" },
"seat": { "zone_id": "zone-1", "seat_id": "zone-1-1-1", "label": "1 Сектор, ряд 1, место 1" },
"checked_in_at": null,
"is_test": false
}],
"meta": { "total": 10 }
}
barcode — это то, что читает сканер с билета. Догружать выгрузку удобно по
updated_since: билеты, купленные после первой выгрузки, иначе не пустят на входе.
Онлайн-скан
POST https://api.ctickets.ru/v1/barcodes/scan
{ "barcode": "337069260809", "event_id": 145, "gate": "Вход А" }
{
"data": {
"allowed": true,
"reason": "ok",
"message": "Проход разрешён",
"ticket": { "number": "TKT-...", "seat": "1 Сектор, ряд 2, место 1" }
}
}
Отказ тоже приходит с кодом 200. Турникету нужна причина, а не HTTP-ошибка, поэтому
решение о проходе — в поле allowed, а разбор — в reason:
| reason | Что показать контролёру |
|---|---|
ok | Проход разрешён |
already_used | Билет уже прошёл — в message время первого прохода |
not_found | Кода нет: чужой билет или подделка |
ticket_refunded, ticket_cancelled | Билет вернули — вход не действителен |
out_of_window | Рано или поздно: окно скана задаёт организатор |
Повторный скан безопасен: второй проход по тому же коду вернёт already_used, а не пустит второй раз. Два турникета, прочитавшие код одновременно, пустят ровно одного.
Заливка офлайн-сканов
POST https://api.ctickets.ru/v1/barcodes/scan/batch
{
"event_id": 145,
"scans": [
{ "barcode": "523409778789", "scanned_at": "2026-08-22T18:41:00+03:00", "gate": "Вход Б" },
{ "barcode": "нет-такого-кода" }
]
}
{
"data": {
"summary": { "accepted": 1, "already_used": 0, "not_found": 1, "rejected": 0 },
"details": [
{ "barcode": "523409778789", "result": "accepted" },
{ "barcode": "нет-такого-кода", "result": "not_found" }
]
}
}
До 5000 сканов за запрос. Повторная заливка того же файла безопасна — уже отмеченные попадут в already_used.