Ваши процессы.
Наш 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://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://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://fams.kz/api/v1/documentsУдостоверение (identity) и паспорт (passport) подходят для требования «документ личности». Остальные типы: driver, medical, consent, organization, insurance_policy, naf_permission, foreign_naf_license. У иностранных паспортов допускаются буквенные номера; ИИН не обязателен.
Решение по отдельному документу: поле review_note возвращается у документов в GET /profiles/{id} и GET /applications/{id}. При status: "changes", status: "cancelled" или status: "expired" показывайте причину пользователю. Администратор отправляет POST /admin/review с kind: "document", id и одним из решений: approve, changes, cancel. Для корректировки и аннулирования поле note обязательно, от 5 до 3000 символов. Решение меняет только указанный документ; после одобрения текущая причина очищается, история сохраняется.
Истечение срока: когда expires_at становится меньше текущей даты, API сохраняет документ со status: "expired". Связанные действующие заявки на сертификат или другой документ FAMS переходят в status: "changes"; причина содержит ID просроченного документа и связанных заявок. Сертификат и QR сразу перестают считаться действующими. Оплата заявки сохраняется. Добавьте новый действующий документ, прикрепите его через PATCH /applications/{id} и повторно вызовите /submit; готовый оплаченный национальный сертификат будет одобрен автоматически без второго списания.
Основные маршруты
| Метод и путь (после /api/v1) | Что делает | Разрешение |
|---|---|---|
| GET /catalog?kind=service | Услуги и тарифы | Публичный |
| GET /events/public | Опубликованный календарь соревнований | Публичный |
| GET /events/public/{id} | Событие, статусы документации и утверждённая таблица итогов | Публичный |
| GET /events/public/{id}/documents/{regulations|results} | Утверждённый регламент или итоговый протокол; ?download=1 скачивает файл | Публичный после одобрения |
| GET /events/public/{id}/documents/additional/{document_id} | Открыть или скачать дополнительный документ соревнования | Публичный для опубликованного события |
| 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 |
| DELETE /profiles/{id} | Удалить анкету, если анкета и фотография никогда не были одобрены | profiles:write, только владелец |
| POST /profiles/{id}/submit | Отправить на проверку | profiles:write |
| GET /profiles/{id}/vehicles | Прочитать архивные записи транспорта старых анкет; добавление и изменение отключено | profiles:read |
| 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 |
| GET, PUT /events/{id}/registration-settings | Классы, экипаж, поля транспорта, колонки Excel и открытие приёма | events:read / events:write |
| POST /events/{id}/registrations/batch | Сохранить черновики или отправить до 100 независимых заявок; документы другой НАФ прикрепляются здесь | applications:write |
| GET /event-registrations/{id} | Своя заявка, snapshot-документы и история статусов | applications:read |
| GET /events/{id}/registrations | Заявки спортсменов, выбранный транспорт и связанные экипажи для организатора | events:read |
| GET /events/{id}/registrations/export | Excel по классам только с колонками, выбранными организатором | 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 |
| GET, POST /events/{id}/additional-documents | Получить или добавить бюллетени, схемы, расписания и другие документы соревнования | events:read / events:write, владелец события |
| DELETE /events/{id}/additional-documents/{document_id} | Удалить один дополнительный документ соревнования | events:write, владелец события |
| POST /events/{id}/submit | Этап: details, regulations, results | events:write |
| GET /contract-templates | Активные шаблоны соглашений и список переменных, включая подпись, печать, номер и QR | events:read |
| GET, POST /contracts | Свои соглашения / создать и сразу сформировать PDF версии 3 | events:read / events:write |
| GET /contracts/{id}/{preview|original|pdf} | Предпросмотр, неизменяемый оригинал или совместимая PDF-ссылка | events:read, владелец или администратор |
| POST /contracts/{id}/request-confirmation | Повторно получить или восстановить PDF с подписью и печатью FAMS | events:write, владелец соревнования |
| POST /contracts/{id}/{replace|cancel} | Создать новую версию или аннулировать с обязательной причиной | events:write |
| POST /contracts/{id}/scan | Загрузить полный подписанный организатором PDF на проверку FAMS | events:write |
| GET /contracts/verify/{token} | Публичная проверка статуса, подписанта и SHA-256 соглашения | Публичный |
| GET /contracts/verify/{token}/pdf | Скачать подтверждённый скан по публичному QR | Публичный после подтверждения FAMS |
| GET, PUT /admin/fams-signing | Единая подпись и печать FAMS для новых соглашений | admin:read / admin:write |
| POST /admin/contracts/{id}/review | Подтвердить или отклонить подписанный скан организатора | admin:write |
| GET /events/{id}/agreement | Устаревший проект соглашения для ранее созданных событий | 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"}}Цена рассчитывается сервером и сохраняется в заявке. Не передавайте свою цену. Для одной анкеты, услуги/категории, выбранной дисциплины и года разрешена только одна активная заявка. Повторное создание вернёт 409 duplicate_application и error.details.application_id существующей заявки — продолжайте её через PATCH, /submit и /pay.
Перед оплатой отправьте заявку на проверку. После успешной оплаты повторный запрос /pay вернёт существующий результат. Национальный сертификат автоматически получает status: "approved", номер и даты действия, как только одновременно одобрены анкета, фото, все обязательные прикреплённые документы и подтверждена оплата. Ручное одобрение самой заявки администратором после этого не требуется. Национальный и международный сертификаты всегда заканчиваются 31 декабря года заявки: сервер устанавливает valid_until сам и игнорирует более позднюю дату клиента. Денежные поля amount_minor — целые тиыны; amount передавайте строкой, например "15000.00".
POST /api/v1/invoices
Idempotency-Key: integration-order-2026-001
Content-Type: application/json
{"amount":"15000.00"}При повторе запроса счёта используйте тот же ключ и ту же сумму. Другую сумму с тем же ключом сервер отклонит. Не создавайте новый ключ из-за сетевого таймаута, пока не проверили результат.
Организатор: соглашение и соревнование
Новый процесс использует workflow_version: 3. Администратор один раз настраивает сторону FAMS через PUT /admin/fams-signing. Загрузите прозрачные PNG/WebP подписи и печати через POST /files с purpose: signature и purpose: stamp. Укажите ФИО и должность подписанта FAMS, UUID файлов и расположение изображений:
{
"signer_name":"Роман Черпрасов",
"signer_position":"Уполномоченный представитель FAMS",
"signature_file_id":"UUID",
"stamp_file_id":"UUID",
"layout":{
"signature":{"x":8,"y":34,"scale":100},
"stamp":{"x":42,"y":10,"scale":100}
}
}
GET /admin/fams-signing возвращает единую настройку FAMS. Оригинальные изображения доступны только администраторам и не имеют публичных URL. Настройка хранится без новой таблицы. Изменение настройки не меняет ранее сформированные PDF.
- Создайте одобренную анкету организатора и соревнование.
- Получите шаблон через
GET /contract-templatesи вызовитеPOST /contracts. Система сразу присвоит номер, создаст QR, вставит подпись и печать FAMS и сохранит неизменяемый PDF. Сторона организатора останется пустой. - Скачайте PDF через
GET /contracts/{id}/original, распечатайте и подпишите сторону организатора вручную. - Загрузите все подписанные страницы одним PDF через
POST /contracts/{id}/scan. Статус станетpending. - FAMS выполняет
POST /admin/contracts/{id}/reviewсconfirmилиreject. При отклонении причина обязательна.
Только подтверждённый скан со статусом confirmed даёт valid: true. Публичный GET /contracts/verify/{token}/pdf возвращает именно подтверждённый скан. До решения FAMS QR показывает, что соглашение не действует. При cancelled или replaced файл остаётся в архиве, а QR показывает недействительный статус.
Журнал фиксирует fams_signing.created/updated, применение подписи и печати FAMS, формирование PDF, скачивание, загрузку скана, решение FAMS, замену и аннулирование вместе с пользователем, временем, IP и хэшами.
Переменные стороны FAMS: {{FAMS_SIGNATURE}}, {{FAMS_STAMP}}, {{FAMS_SIGNER_NAME}}, {{FAMS_SIGNER_POSITION}}, {{FAMS_SIGNED_AT}}, {{DOCUMENT_NUMBER}}, {{DOCUMENT_QR}}. Сторона организатора в новом процессе остаётся пустой для ручного подписания.
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. Отметка выгрузки означает подготовку файла, а не отправку третьим лицам или оформление полиса.