Mosaqo API для разработчиков
REST API над тем же пространством, которое вы видите в приложении. Всё ниже работает с одним API-ключом и любым HTTP-клиентом.
Что можно сделать
- Создавать QR-коды из своих записей — по одному или десять тысяч из CSV.
- Менять, куда ведёт напечатанный код, одним вызовом и без перепечатки.
- Скачивать готовую карточку в PNG, SVG или PDF и прикреплять её к записи CRM.
- Читать сканирования и сводную аналитику с учётом правил приватности вашего пространства.
- Получать подписанные webhooks, когда коды создаются, публикуются, меняются или архивируются.
Быстрый старт
Создайте ключ в разделе Bulk & API своего пространства, отметьте скоупы qr:write и qr:read и скопируйте секрет — его показывают только один раз.
Проверьте ключ и узнайте, какое пространство он открывает:
curl https://api.mosaqo.app/v1/public-api/me \
-H "Authorization: Bearer $MOSAQO_KEY"Создайте динамический QR-код:
curl -X POST https://api.mosaqo.app/v1/public-api/qr \
-H "Authorization: Bearer $MOSAQO_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Autumn campaign",
"mode": "dynamic",
"contentType": "url",
"content": { "targetUrl": "https://example.com/autumn" }
}'Опубликуйте его — именно это включает редирект, — а затем заберите изображение для печати:
curl -X POST https://api.mosaqo.app/v1/public-api/qr/$QR_ID/publish \
-H "Authorization: Bearer $MOSAQO_KEY"
curl https://api.mosaqo.app/v1/public-api/qr/$QR_ID/image?format=png&size=2048 \
-H "Authorization: Bearer $MOSAQO_KEY" -o campaign.pngСпустя месяцы, когда кампания сменится, перенацельте тот же напечатанный код без перепечатки:
curl -X POST https://api.mosaqo.app/v1/public-api/qr/$QR_ID/destination \
-H "Authorization: Bearer $MOSAQO_KEY" \
-H "Content-Type: application/json" \
-d '{ "url": "https://example.com/winter" }'Аутентификация
Отправляйте секрет любым из двух способов. Оба поддерживаются на протяжении всей v1.
Authorization: Bearer mosaqo_xxx
X-Mosaqo-API-Key: mosaqo_xxxКлюч принадлежит ровно одному пространству, поэтому идентификатор пространства в пути не нужен: достаточно /v1/public-api/qr. Прежняя форма /v1/public-api/workspaces/{workspaceId}/qr тоже работает.
| Скоуп | Даёт право |
|---|---|
qr:read | Читать список и содержимое QR-кодов, папки и шаблоны |
qr:write | Создавать, изменять, перенацеливать, публиковать, архивировать и удалять |
exports:read | Скачивать отрисованные карточки |
analytics:read | Сводную аналитику и отдельные сканирования |
bulk:write | Создавать и читать пакетные задания |
webhooks:write | Управлять подписками на webhooks |
Ключ можно отозвать, ограничить сроком действия или IP allow-list. Если ключ отклонён именно из-за allow-list, мы говорим об этом прямо, а не выдаём его за недействительный.
Пагинация
Списки используют keyset-пагинацию. Возвращайте pagination.nextCursor без изменений: строки никогда не повторятся и не исчезнут из-за того, что что-то отредактировали посреди синхронизации, — а это важно для ночного прогона.
curl "https://api.mosaqo.app/v1/public-api/qr?limit=50&cursor=$CURSOR" \
-H "Authorization: Bearer $MOSAQO_KEY"Чтобы опрашивать изменения, а не проходить всё заново, добавьте updatedSince=2026-08-05T00:00:00Z.
Ошибки
Каждая ошибка несёт стабильный code, по которому можно ветвиться, понятный человеку message и requestId, который стоит указать в обращении в поддержку.
{
"error": "This API key does not have the qr:write scope.",
"message": "This API key does not have the qr:write scope.",
"code": "insufficient_scope",
"details": { "required": "qr:write", "granted": ["qr:read"] },
"requestId": "req-42"
}| Статус | Коды | Что делать |
|---|---|---|
| 401 | invalid_api_key | Ключа нет, он отозван или истёк. Попросите пользователя подключиться заново. |
| 403 | insufficient_scope, ip_not_allowed, workspace_mismatch, quota_exceeded | Ключ действителен, но не имеет права на это действие. Переподключение не поможет. |
| 404 | not_found | Такой записи в этом пространстве нет. |
| 409 | idempotency_conflict, idempotency_in_progress | Ключ повторно использован с другими данными или первая попытка ещё выполняется. |
| 422 | validation_failed, invalid_cursor, approval_required, contrast_check_failed | Исправьте входные данные. Никогда не повторяйте запрос без изменений. |
| 429 | rate_limited | Подождите число секунд из Retry-After. |
Лимиты запросов
Каждый ответ несёт ваш текущий остаток, а не только те, которые отклонены:
X-RateLimit-Limit: 600
X-RateLimit-Remaining: 574
X-RateLimit-Reset: 1785942718Лимит — это защита от злоупотреблений, а не тариф: он не подразумевает ни квоты, ни оплаты, ни перехода на более высокий план.
Идемпотентность
Idempotency-Key необязателен. Передайте его — любую уникальную строку — и повтор того же запроса в течение 24 часов воспроизведёт исходный ответ вместо второго выполнения. Тот же ключ с другими данными вернёт 409. Без ключа запрос просто выполнится, без защиты от повтора.
Дальше
- Webhooks — каталог событий и как проверить доставку.
- Рецепты — Make, Zapier, n8n и подходы для CRM.
- Справочник API — все эндпоинты с живой консолью.