Штрихкоды и вход

Два сценария контроля входа, и они не заменяют друг друга: онлайн — турникет спрашивает нас в момент прохода; офлайн — коды заранее выгружаются в автономный сканер, а отметки заливаются потом. Офлайн нужен потому, что связь на площадке пропадает именно тогда, когда идёт основной поток людей.

Выгрузка кодов

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.

Вопросы по интеграции — api@ctickets.ru. Ключи и журнал запросов — в кабинете организатора, раздел «API и интеграции».