API Qronika
API позволяет вашей CRM, сайту или внутренней системе работать с QR-кодами и папками без ручных действий в кабинете.
Доступ
API доступен на тарифах Business и Enterprise и работает с данными аккаунта или выбранной команды. Данные разных команд изолированы. Выпускать ключи и управлять ими может владелец или администратор пространства. Ключ выполняет только действия, разрешённые его scopes; редакторская роль сама по себе не даёт права выпускать ключи.
Как выпустить ключ
- Откройте «API-ключи» в меню аккаунта.
- Переключитесь в нужный контекст.
- Укажите понятное название и выберите разрешения на просмотр или изменение QR-кодов, папок и аналитики.
- Скопируйте секрет сразу: повторно он не показывается.
Ответы и повтор запросов
Проверяйте HTTP-статус и JSON-ответ перед повтором запроса. Списки возвращаются постранично, частота запросов
ограничена. Для безопасного повтора POST /qr-codes используйте заголовок Idempotency-Key. На создание папок и другие методы эта защита не распространяется.
Отзыв доступа
Отозванный ключ перестаёт работать сразу. При удалении команды все её ключи также перестают работать.
Начало работы
export API_BASE="https://qronika.ru/api/v1"
export API_KEY="YOUR_API_KEY"
export IDEMPOTENCY_KEY="unique-request-0001"
Все запросы выполняются через HTTPS. Подставьте адрес сервиса в API_BASE (с /api/v1), секрет — в API_KEY. QR_ID, FOLDER_ID и USER_ID в примерах обозначают UUID. Полный ключ доступен только при выпуске; не вставляйте его в публичный код.
Для чтения: qr:read, папок: folders:read, статистики: analytics:read. Изменения QR требуют qr:write, изменения папок и перемещение — folders:write. Создавайте ключ с минимально необходимыми разрешениями.
Один ключ допускает 120 запросов в минуту. При 429 дождитесь Retry-After (секунды). API требует Business или Enterprise на каждом запросе: при окончании доступа возвращается 403 api_unavailable, ключи сохраняются. После восстановления тарифа действующий ключ снова работает.
Как избежать повторного создания QR
Для POST /qr-codes передайте Idempotency-Key длиной 8–128 символов: латинские буквы, цифры и знаки ._:-. Без заголовка или с пустым значением запрос также принимается, но каждый повтор может создать ещё один QR.
Защита действует 24 часа и относится к конкретному API-ключу. Повторите тот же JSON с тем же ключом идемпотентности и тем же API-ключом: получите сохранённый результат. Не меняйте типы значений и порядок полей. Другое тело с тем же ключом даёт 409 idempotency_conflict.
При таймауте не создавайте новый ключ идемпотентности и не переключайтесь на другой API-ключ: первый запрос мог уже завершиться. После 24 часов прежний ключ может создать новый QR, поэтому сначала сверьте результат предыдущей операции. Для самостоятельной новой операции используйте новый ключ.
Пагинация QR: page по умолчанию 1, per_page — 20. Целый размер страницы ограничивается диапазоном 1–100; неверное значение использует 20. Страница за концом списка возвращает пустой массив. Фильтры: folder_id, type, mode, search. Список папок возвращается целиком.
Для перемещения folder_id обязателен: UUID выбирает папку, null переносит QR в корень. Создание QR использует поле названия qr_name, обновление — name; при PATCH название обязательно. Для динамического QR передавайте также новое содержимое соответствующего типа либо строковый destination_url.
Ключ действует календарный год. За 7 дней до окончания появляется «Продлить на год». Приостановка обратима и не освобождает лимит, отзыв окончателен. Название можно менять без изменения секрета.
Примеры ответов иллюстративные: реальные ID, даты и счётчики будут другими. Для запросов с удалением используйте тестовые объекты. 204 означает успешное выполнение без тела ответа.
Список QR-кодов
GET /qr-codes?page=1&per_page=20 · Разрешение: qr:read
curl -i -X GET "$API_BASE/qr-codes?page=1&per_page=20" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json"
HTTP 200
{
"data": [
{
"id": "QR_ID",
"name": "CRM",
"type": "url",
"mode": "dynamic",
"folder_id": null,
"destination_url": "https://example.com",
"scan_count": 0,
"created_at": "2026-10-15 10:00:00"
}
],
"meta": {
"page": 1,
"per_page": 20,
"total": 1,
"pages": 1
}
}
Создать QR-код
POST /qr-codes · Разрешение: qr:write
curl -i -X POST "$API_BASE/qr-codes" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $IDEMPOTENCY_KEY" \
--data '{"qr_name": "CRM", "type": "url", "mode": "dynamic", "value": "https://example.com"}'
HTTP 201
{
"data": {
"id": "QR_ID",
"name": "CRM",
"type": "url",
"mode": "dynamic",
"folder_id": null,
"destination_url": "https://example.com",
"scan_count": 0,
"created_at": "2026-10-15 10:00:00"
}
}
Получить QR-код
GET /qr-codes/QR_ID · Разрешение: qr:read
curl -i -X GET "$API_BASE/qr-codes/QR_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json"
HTTP 200
{
"data": {
"id": "QR_ID",
"name": "CRM",
"type": "url",
"mode": "dynamic",
"folder_id": null,
"destination_url": "https://example.com",
"scan_count": 0,
"created_at": "2026-10-15 10:00:00"
}
}
Изменить Dynamic QR
PATCH /qr-codes/QR_ID · Разрешение: qr:write
curl -i -X PATCH "$API_BASE/qr-codes/QR_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{"name": "CRM", "value": "https://example.com/new"}'
HTTP 200
{
"data": {
"id": "QR_ID",
"name": "CRM",
"type": "url",
"mode": "dynamic",
"folder_id": null,
"destination_url": "https://example.com/new",
"scan_count": 0,
"created_at": "2026-10-15 10:00:00"
}
}
Удалить QR-код
DELETE /qr-codes/QR_ID · Разрешение: qr:write
curl -i -X DELETE "$API_BASE/qr-codes/QR_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json"
HTTP 204
(без тела ответа)
Статистика QR-кода
GET /qr-codes/QR_ID/stats · Разрешение: analytics:read
curl -i -X GET "$API_BASE/qr-codes/QR_ID/stats" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json"
HTTP 200
{
"data": {
"qr_code_id": "QR_ID",
"scan_count": 0
}
}
Переместить QR-код
POST /qr-codes/QR_ID/move · Разрешение: folders:write
curl -i -X POST "$API_BASE/qr-codes/QR_ID/move" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{"folder_id": "FOLDER_ID"}'
HTTP 200
{
"data": {
"id": "QR_ID",
"folder_id": "FOLDER_ID"
}
}
Список папок
GET /folders · Разрешение: folders:read
curl -i -X GET "$API_BASE/folders" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json"
HTTP 200
{
"data": [
{
"id": "FOLDER_ID",
"userId": "USER_ID",
"name": "CRM",
"qrCount": 1,
"createdAt": "2026-10-15 10:00:00"
}
]
}
Создать папку
POST /folders · Разрешение: folders:write
curl -i -X POST "$API_BASE/folders" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{"name": "CRM"}'
HTTP 201
{
"data": {
"id": "FOLDER_ID"
}
}
Переименовать папку
PATCH /folders/FOLDER_ID · Разрешение: folders:write
curl -i -X PATCH "$API_BASE/folders/FOLDER_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
--data '{"name": "CRM 2"}'
HTTP 200
{
"data": {
"id": "FOLDER_ID"
}
}
Удалить папку
DELETE /folders/FOLDER_ID · Разрешение: folders:write
curl -i -X DELETE "$API_BASE/folders/FOLDER_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Accept: application/json"
HTTP 204
(без тела ответа)
Параметры создания
Обязательные поля: qr_name (1–255 символов), type и данные выбранного типа. mode: static (по умолчанию) или dynamic. folder_id необязателен. Название папки — 1–48 символов. GET /qr-codes/{id}/stats возвращает суммарное scan_count, а не полный аналитический отчёт.
Дизайн передаётся при POST /qr-codes в том же JSON: foreground и background — HEX #RRGGBB; size — 256–1200 (по умолчанию 720); margin — 0–16 модулей (по умолчанию 1); corner_radius — 0–12; error_correction — L/M/Q/H.
module_style: square, rounded_soft, rounded, rounded_strong, dots, dots_small, diamond, hexagon, vertical, horizontal, leaf, star. eye_style и eye_inner_style принимают те же значения, а также circle и pointy. eye_outer_color и eye_inner_color — HEX.
gradient_enabled и background_transparent включаются строкой "1". Для градиента: gradient_color (HEX), gradient_type (linear, radial, vertical, horizontal, diagonal, inverse_diagonal), gradient_angle (0–360). JSON boolean true вместо строки "1" не включает эти параметры. Загрузка логотипа и скачивание изображения отдельными API-методами сейчас не предоставляются.
Ошибки и диагностика
Ошибки обработчиков API имеют формат: {"error":{"code":"insufficient_scope","message":"…"}}. Используйте HTTP-статус и code, а не текст сообщения. Авторизованные ответы содержат X-Request-Id; передайте его поддержке. Для непредвиденной ошибки идентификатор также доступен в журнале ключа. Ранний отказ веб-сервера или ограничения тела может иметь другой формат и не попасть в журнал ключа: сначала проверяйте HTTP-статус и Content-Type.
- 400 invalid_idempotency_key — неверный Idempotency-Key.
- 401 unauthorized / invalid_api_key — нет ключа, ключ истёк, приостановлен, отозван или его владелец/создатель недоступен.
- 403 insufficient_scope — не хватает разрешения; api_unavailable — тариф не предоставляет API; creator_unavailable — создатель недоступен.
- 403 insufficient_permissions — отказ доступа в проверке перемещения или удаления QR.
- 404 not_found — объект не найден в пространстве ключа.
- 409 idempotency_conflict / request_in_progress / idempotency_expired — конфликт, операция ещё выполняется или требуется новый ключ идемпотентности.
- 413 — тело API-запроса превышает 256 КиБ. Сократите запрос; тот же большой запрос повторять не нужно.
- 422 validation_error — неверные данные, лимит объектов или недоступная возможность. Исправьте запрос перед повтором.
- 429 rate_limit_exceeded — превышена частота запросов.
- 500 — внутренняя ошибка: проверьте журнал и обратитесь в поддержку с ID запроса.
Содержимое QR-кодов
Для URL и текста — value; email — email, subject, body; телефона — phone; Wi-Fi — ssid, encryption, password, hidden; vCard — name, organization, phone, email, url; SMS — phone, message; геопозиции — latitude, longitude; WhatsApp — phone, message. Для POST название QR задаётся qr_name, для PATCH — name. Тип и дизайн после создания не меняются; назначение меняется только у Dynamic QR.
Журнал хранится 90 дней и включает ответы 403 по тарифу, 429 и внутренние ошибки после распознавания ключа. Заголовок Authorization и секрет не сохраняются; значения тела запроса очищаются. Неопознанный или отозванный ключ не привязывается к пользовательскому журналу.