Ваши процессы.
Наш API.
API даёт доступ к тем же анкетам, файлам, заявкам и соревнованиям, что и личный кабинет. Доступ ограничен владельцем данных и разрешениями ключа.
Создать API-ключ ↗Скачать спецификацию OpenAPI 3.1 JSON для импорта в Postman и другие инструменты.
1. Получите ключ
Войдите в кабинет → «Доступ к API» → «Создать ключ». Укажите название интеграции, срок и минимальный набор разрешений. Сохраните ключ: он показывается только один раз. Храните его на своём сервере, в переменной окружения; не добавляйте в публичный JavaScript.
Authorization: Bearer YOUR_TOKEN Accept: application/json
Для Bearer-запросов CSRF не требуется. Для браузерной сессии сначала вызовите GET /api/v1/session, затем передавайте X-CSRF-Token во всех изменяющих запросах. CORS для сторонних браузерных сайтов по умолчанию не открыт: интеграции работают с сервера.
Регистрация, запрос восстановления пароля и форма контактов требуют одноразовую CAPTCHA. В той же сессии вызовите GET /captcha?purpose=register|forgot|contact, покажите PNG из data.image и отправьте captcha_id вместе с пятью символами в captcha_answer. Код действует 10 минут и один раз; новый код отменяет предыдущий.
2. Первый запрос
curl -H "Authorization: Bearer YOUR_TOKEN" \ https://nw.fams.kz/api/v1/profiles
{
"data": [{"id": 123, "kind": "athlete", "name": "Имя спортсмена"}],
"meta": {},
"request_id": "номер запроса"
}3. Загрузите файл
Принимаются JPG, PNG, WebP и PDF до 20 МБ. Файлы хранятся вне публичной папки. Сохраните полученный data.id и используйте его как file_id или photo_id.
curl -X POST -H "Authorization: Bearer YOUR_TOKEN" \ -F "file=@passport.pdf" -F "purpose=identity" \ https://nw.fams.kz/api/v1/files
4. Прикрепите паспорт
curl -X POST -H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"profile_id":123,"type":"passport","file_id":"FILE_UUID","number":"N1234567","country":"Казахстан","issued_at":"2025-01-15","expires_at":"2035-01-15"}' \
https://nw.fams.kz/api/v1/documentsУдостоверение (identity) и паспорт (passport) подходят для требования «документ личности». Остальные типы: driver, medical, consent, organization. У иностранных паспортов допускаются буквенные номера; ИИН не обязателен.
Причина отказа в документе: поле review_note возвращается у документов в GET /profiles/{id} и GET /applications/{id}. При status: "rejected" показывайте его пользователю. Администратор отклоняет документ через POST /admin/review: kind: "document", id, decision: "changes", note; причина обязательна, от 5 до 3000 символов. После одобрения текущая причина очищается, история решения сохраняется.
Основные маршруты
| Метод и путь (после /api/v1) | Что делает | Разрешение |
|---|---|---|
| GET /catalog?kind=service | Услуги и тарифы | Публичный |
| GET /events/public | Опубликованный календарь соревнований | Публичный |
| GET /events/public/{id} | Событие, статусы документации и утверждённая таблица итогов | Публичный |
| GET /events/public/{id}/documents/{regulations|results} | Утверждённый регламент или итоговый протокол; ?download=1 скачивает файл | Публичный после одобрения |
| GET /services/prices | Текущий МРП и точная цена всех активных услуг | applications:read |
| GET /profiles | Свои анкеты | profiles:read |
| GET /profiles/summary | Компактный список спортсменов со счётчиками документов, заявок, сертификатов и соревнований | profiles:read |
| GET /profiles/{id}/portfolio | Полное досье одной анкеты: документы, сертификаты, заявки и участие в соревнованиях | profiles:read, только владелец |
| POST /profiles | Новая анкета: kind, data, photo_id | profiles:write |
| PATCH /profiles/{id} | Изменить данные анкеты | profiles:write |
| POST /profiles/{id}/submit | Отправить на проверку | profiles:write |
| POST /documents | Прикрепить документ к анкете | profiles:write |
| PATCH /documents/{id} | Изменить неиспользуемый документ | profiles:write |
| GET /files | Мои файлы | files:read |
| POST /files | Загрузить файл, multipart/form-data | files:write |
| GET /files/{uuid} | Открыть; ?download=1 — скачать | files:read |
| DELETE /files/{uuid} | Убрать неиспользуемый файл | files:write |
| GET /applications | Свои заявки | applications:read |
| POST /applications/quote | Расчёт стоимости | applications:write |
| POST /applications | Черновик заявки: profile_id, service_id, document_ids, data | applications:write |
| PATCH /applications/{id} | Изменить черновик / возвращённую заявку | applications:write |
| POST /applications/{id}/submit | Проверить комплект и отправить | applications:write |
| POST /applications/{id}/pay | Оплата с баланса, повторное списание исключено | wallet:write |
| GET /applications/{id}/certificate | Готовый документ после одобрения и оплаты | applications:read |
| PUT /applications/{id}/sharing | Разрешить или закрыть документы международной лицензии по QR | applications:write, только владелец |
| GET /applications/{id}/qr | Скачать QR международной лицензии после одобрения и оплаты | applications:read |
| GET /event-registrations | Свои заявки на участие в соревнованиях | applications:read |
| GET /events/{id}/registration-options | Подходящие действующие сертификаты | applications:read |
| POST /events/{id}/register | Подать заявку спортсмена; оплата не требуется | applications:write |
| GET /events/{id}/registrations | Заявки спортсменов для организатора | events:read |
| PATCH /events/{id}/registrations/{registration_id} | Одобрить, вернуть с причиной или отказать | events:write |
| GET /messenger | Только разрешённые диалоги: администрация и связанные соревнования | notifications:read |
| GET /messenger/{perspective}/registrations/{id} | Переписка по конкретной заявке на участие | notifications:read |
| POST /messenger/{perspective}/registrations/{id}/messages | Отправить сообщение разрешённой стороне | notifications:write |
| GET, POST /events | Свои соревнования / создать черновик | events:read / events:write |
| PATCH /events/{id} | Данные или файл этапа | events:write |
| POST /events/{id}/submit | Этап: details, regulations, results | events:write |
| GET /events/{id}/agreement | Проект соглашения PDF | events:read |
| GET /wallet | Баланс, счета и история операций | wallet:read |
| POST /invoices | Счёт: amount строкой, Idempotency-Key | wallet:write |
| POST /invoices/{id}/checkout | Параметры формы банка | wallet:write |
| POST /invoices/{id}/verify | Сверить статус с банком | wallet:write |
| GET /notifications | Уведомления | notifications:read |
| POST /notifications/{id}/read | Отметить прочитанным | notifications:write |
| GET /verify/{token} | Публичная проверка без личных данных | Публичный |
| GET /verify/{token}/documents | Разрешённые документы действующей международной лицензии | Публичный по QR и согласию владельца |
Заявка и сумма
GET /services/prices — официальный список тарифов для пользователя или интеграции. Ответ содержит текущий МРП в mrp.amount_minor, коэффициент каждой услуги в services[].mrp, сумму для РК в price_kz_minor и полную сумму для СНГ в price_cis_minor, если территория разрешена. Поля _minor указаны в целых тиынах. Показывайте эти значения пользователю, но окончательной считайте сумму, которую сервер записал в созданную заявку.
Национальный сертификат: страхование предусмотрено автоматически. Единственный платёж по такой заявке — страховой взнос по выбранной категории; отдельной услуги или флага подключения страховки нет. Старая формула сохранена: тариф категории × МРП, для разрешённой территории СНГ добавляется доплата категории × МРП. insurance_territory задаёт только территорию KZ/CIS, по умолчанию KZ. insurance_coverage_minor — размер покрытия, не сумма взноса. Ответ расчёта и заявки содержит payment.purpose: "insurance", payment.insurance_required: true и payment.label. Это поля ответа, их нельзя использовать для отключения страхования. Для остальных услуг назначение платежа — service. Оплата сама по себе не подтверждает выдачу страхового полиса.
POST /api/v1/applications
Content-Type: application/json
{"profile_id":123,"service_id":4,"document_ids":[10,11,12],"data":{"team":"Название команды","sport":"auto","insurance_territory":"KZ"}}Цена рассчитывается сервером и сохраняется в заявке. Не передавайте свою цену. Перед оплатой отправьте заявку на проверку. После успешной оплаты повторный запрос /pay вернёт существующий результат. Денежные поля amount_minor — целые тиыны; amount передавайте строкой, например "15000.00".
POST /api/v1/invoices
Idempotency-Key: integration-order-2026-001
Content-Type: application/json
{"amount":"15000.00"}При повторе запроса счёта используйте тот же ключ и ту же сумму. Другую сумму с тем же ключом сервер отклонит. Не создавайте новый ключ из-за сетевого таймаута, пока не проверили результат.
Организатор: порядок действий
- Создайте
profilesсkind: "organizer", заполните реквизиты и дождитесь одобрения. - Создайте событие в
/events: profile_id, service_id, discipline_id, title, location, starts_at, ends_at, reserve_at. - Скачайте
/events/{id}/agreement, проверьте и подпишите проект. Загрузите скан и обновите событие:{"stage":"agreement","files":{"agreement":"UUID"}}. - Отправьте этап
{"stage":"details"}. Вdata.application_idпоявится заявка на взнос. Оплатите её. - После одобрения загрузите и отправьте
regulations. - После соревнования добавьте участников через
POST /events/{id}/participants. Полеcertificateпринимает номер сертификата, код проверки или полную QR-ссылку. Сервер сам подставит спортсмена и проверит одобрение, оплату и срок действия на даты соревнования. Передайтеcategory,start_number,result_status,placeиresult. Список возвращаетGET /events/{id}/participants; результат меняется черезPATCH, участник удаляется черезDELETE /events/{id}/participants/{application_id}. - Приложите итоговый PDF и отправьте этап
results. После отправки список закрывается до решения администратора.
Telegram-бот
GET /telegram показывает состояние подключения, POST /telegram создаёт одноразовую ссылку на 10 минут, DELETE /telegram отключает бот. Изменения доступны только через браузерную сессию с CSRF; API-ключом привязку менять нельзя. Пароль и ключ API в Telegram не передаются. Транспортный /telegram/webhook предназначен только для Telegram и защищён заголовком X-Telegram-Bot-Api-Secret-Token. Настройка сервера описана в docs/telegram-bot.md.
Ошибки и ограничения
401 — вход или токен; 403 — недостаточно прав; 404 — запись отсутствует или не ваша; 409 — конфликт статуса, средств или ключа; 419 — CSRF; 422 — поля и требования; 429 — лимит запросов; 503 — интеграция отключена. В ошибке есть error.code, error.message, иногда error.details.missing. При обращении в поддержку передайте request_id, но не ключ API.
Списки поддерживают page и limit (1–100). Ответ содержит meta.total. Анкеты и собственные события возвращаются целиком в пределах аккаунта. Даты — YYYY-MM-DD; локальная временная зона — Казахстан, UTC+5.
Администраторы
Административные маршруты требуют роли администратора и scopes admin:read / admin:write. Доступны /admin/overview, /admin/queue, /admin/review, /admin/catalog, /admin/users, /admin/athletes, /admin/ledger, /admin/audit, /admin/export. GET /admin/athletes поддерживает фильтры status, certificate (issued, not_issued, pending) и q (ФИО, ИИН, телефон, город, email или ID). Ответ показывает, получил ли спортсмен сертификат, последнюю заявку, номер и срок действия, а также владельца аккаунта и счётчики документов и заявок. CSV с теми же признаками доступен по GET /admin/export?kind=athletes. Ручные денежные корректировки, сторно, смена прав и управление ключами дополнительно требуют браузерной сессии и подтверждения пароля.
Банковский callback не является подтверждением оплаты: сервер самостоятельно запрашивает банк и сверяет счёт, сумму, валюту и терминал. Реальные платежи и письма включаются после настройки и проверки окружения.
PUT /admin/profiles/{id}/owner переносит анкету на другой активный аккаунт. Передайте current_user_id, target_user_id, причину от 5 символов и пароль администратора. В одной транзакции переходят связанные документы, заявки, сертификаты, соревнования организатора, файлы и контекст чатов соревнований. Снимки выданных сертификатов, оплаченные суммы и бухгалтерские проводки не переписываются. Публичный доступ к документам международной лицензии по QR закрывается до нового согласия владельца. Оба владельца получают уведомление, действие сохраняется в аудите.
Национальные сертификаты: три списка
Отдельный раздел: Нац. сертификаты. GET /admin/national возвращает национальные сертификаты и личные списки администратора: review, insurance, print. Фильтры: year, q, service_id, status, paid, insurance, print, пагинация page/limit.
POST /api/v1/admin/national/lists/insurance
{"operation":"add","ids":[123,124]}
POST /api/v1/admin/national/lists/insurance/export
{"ids":[123,124]}
Другие операции списка: remove, clear, auto с year. До 200 записей. Для страховой и печати нужны одобрение и оплата; auto добавляет ещё не выгруженные записи выбранного года. Выгрузка возвращает 201, data.file.download_url и data.count. Скачайте URL отдельным GET с разрешением files:read. Страховая — XLSX с 10 прежними колонками; печать — ZIP с document.xlsx, foto/ и qr/. Пустые шаблоны: GET /admin/national/templates/insurance и /print.
Обработка: POST /admin/national/lists/review/review, поля ids, decision (approve/changes/cancel), note. Возврат и отклонение требуют причины от 5 символов. Проверяйте data.succeeded и data.failed при HTTP 200. Отклонение не возвращает деньги. Выгрузка проверяет всю подборку: 422 error.details.records указывает проблемные записи; 409 — подборка изменилась. Максимум 20 попыток выгрузки в час и 300 МБ фотографий на ZIP. Отметка выгрузки означает подготовку файла, а не отправку третьим лицам или оформление полиса.