DocHub API
Мобильное приложение — API v1
Базовый путь: /api/mobile/v1. Авторизация: Bearer JWT пользователя; X-Api-Key на телефон не передаётся.
Скачать спецификацию OpenAPI. Это API новой версии: включение на сервере требует миграций и настройки собственного криптосервиса.
POST /auth/login— email/password;POST /auth/refresh— refresh_token;POST /auth/logout— выход.GET /documents— список;GET /documents/{id}— карточка;GET /documents/{id}/file— оригинал.POST /signing/challenges— doc_id;POST /signing/complete— зашифрованный конверт ЭЦП.GET /signing/operations/{challenge_id}— результат после обрыва связи;GET /documents/{id}/evidence— оригинал и CMS-подписи.
Поля конверта: challenge_id, encrypted_key, iv, ciphertext, tag. Алгоритм RSA-OAEP SHA-256 + AES-256-GCM; AAD берётся из challenge. Не отправляйте P12 и пароль открытым JSON.
Базовый URL: https://doc-hub.net. Эта страница открыта без входа в систему — справочник для внешних интеграций (1С, CRM, ERP) и своей команды.
📘 Аутентификация
Два способа, для каждого запроса достаточно одного.
| Способ | Заголовок | Для кого |
|---|---|---|
| X-Api-Key | X-Api-Key: <ключ> | Серверные интеграции (1С, CRM) — ключ конкретной компании, создаётся в её профиле (см. ниже). Работает и старый общий ключ (переменная DOCHUB_API_KEY) — для обратной совместимости, новым интеграциям он не нужен. |
| Bearer JWT | Authorization: Bearer <токен> | От имени залогиненного пользователя DocHub. Токен выдаёт /api_proxy/supabase_proxy.php, action auth.signIn. |
Ключ интеграции на компанию — Профиль компании → «Ключи интеграции API» → «Создать ключ» (нужны права администратора компании). Ключ показывается один раз в момент создания — скопируйте сразу, повторно узнать его нельзя, только отозвать и создать новый. Один ключ = одна компания: company_id в теле запроса определяется по ключу автоматически, сервер отклонит запрос, если он не совпадёт. До 20 активных ключей на компанию.
Партнёрский ключ (по БИН, без предварительной регистрации) — для интегратора, работающего от лица многих своих клиентов (например бухгалтерский SaaS). Компания не обязана быть заранее зарегистрирована в DocHub: сервер резолвит её по заголовку X-Company-Bin на каждый запрос и создаёт компанию автоматически, если такого БИН ещё нет. company_id в теле запроса тогда можно не передавать вовсе — подставляется сам. Такой ключ не создаётся в профиле компании — выдаётся вручную командой DocHub (scripts/create_partner_api_key.js), обратитесь к нам.
curl https://doc-hub.net/api/invoice/create \
-H "X-Api-Key: <партнёрский ключ>" \
-H "X-Company-Bin: <БИН клиента интегратора>" \
-H "Content-Type: application/json" \
-d '{"invoice_number":"1", ...}' # без company_id — резолвится по БИН
Отдельные токены другого вида (например для 1С-синхронизации ЭСФ/эАВР) — свои, см. раздел ниже.
# серверная интеграция — ключ компании из её профиля curl https://doc-hub.net/api/invoice/create \ -H "X-Api-Key: <ваш ключ компании>" ... # от имени залогиненного пользователя DocHub curl https://doc-hub.net/api/bpm/my-tasks?actor_id=... \ -H "Authorization: Bearer <JWT>"
✍️ Согласование документов
Запуск и подписание маршрута согласования — договор, акт, любой файл.
Создаёт документ, маршрут согласования, добавляет согласующих, загружает файл. multipart/form-data (с файлом) или application/json (без).
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
title | string | да | Название документа |
company_id | uuid | да | Компания-инициатор |
approvers | array | да | [{ user_id? | email, name?, iin_bin?, role, order_num, deadline? }] — role: approver | signer |
file | file | нет | PDF/DOCX/XLSX/изображение, до 25 МБ |
doc_type | string | нет | contract (default) · act · invoice · nda · agreement · poa · order · other · avr · schet_faktura |
flow_type | string | нет | sequential (default) · parallel |
counterparty, amount, currency, doc_date, description | — | нет | Метаданные документа |
iin_bin у согласующего — сервер сверяет его с ИИН/БИН из сертификата ЭЦП при подписании и отклоняет чужую подпись (403 IIN_BIN_MISMATCH).
/api/approval/start
← 200 {
success, doc_id, flow_id,
public_url: "https://doc-hub.net/p/{doc_id}",
approver_links: [{ order_num, name, email, role, sign_token,
sign_url: "https://doc-hub.net/p/{doc_id}?t={sign_token}" }]
}
Сохраняет подпись согласующего. Вызывается с публичной страницы /p/{docId}?t={token} — токен сам по себе и есть авторизация конкретного подписанта.
| Поле | Обязательно | Описание |
|---|---|---|
sign_token | да (приоритетно) | Персональный токен подписанта |
signed_xml | да | Подписанный XML от NCALayer |
doc_id | если нет токена | UUID документа (запасной способ) |
← 200 { success, approver_id, all_signed, doc_status }
Публичная отдача оригинального файла документа — используется на странице подписания и в превью.
Генерирует печатный PDF со штампом ЭЦП и QR-кодом после того, как документ подписан.
💵 Счета на оплату
Собирает «Счёт на оплату» из структурированных данных (реквизиты поставщика подтягиваются из companies по company_id), рендерит PDF и сразу запускает согласование — тонкая обёртка над /api/approval/start.
| Поле | Обязательно | Описание |
|---|---|---|
company_id | да | Компания-поставщик |
invoice_number, invoice_date | да | Номер и дата счёта |
buyer | да | { name, bin?, address? } |
items | да | [{ name, qty?, unit?, price }], минимум 1 |
approvers | да | тот же формат, что в /approval/start |
contract, kbe, knp, vat_rate, currency | нет | Реквизиты платежа; vat_rate — доля, напр. 0.12 |
/api/invoice/create
← 200 { success, doc_id, flow_id, public_url, file_url, approver_links, total, total_words }
📋 Акты выполненных работ (АВР)
Собирает обычный печатный «Акт выполненных работ (оказанных услуг)» по образцу официального бланка (Форма Р-1, Приложение 50 к приказу Министра финансов РК от 20.12.2012 № 562) — это не электронный эАВР через esf.gov.kz (см. раздел «ИС ЭСФ — документы» ниже для того случая). Реквизиты исполнителя подтягиваются из companies по company_id, рендерится PDF и сразу запускается подписание обеими сторонами по персональным ссылкам — тонкая обёртка над /api/approval/start, аналогично /api/invoice/create.
| Поле | Обязательно | Описание |
|---|---|---|
company_id | да | Компания-исполнитель (сторона «Сдал») |
avr_number, avr_date | да | Номер и дата акта |
customer | да | { name, bin?, address? } — Заказчик (сторона «Принял») |
items | да | [{ name, work_date?, report_info?, unit?, qty?, price }], минимум 1 |
executor_signer | да | { user_id?, name, email?, iin_bin?, deadline? } — подписывает «Сдал (Исполнитель)» |
customer_signer | да | { user_id?, name, email?, iin_bin?, deadline? } — подписывает «Принял (Заказчик)» |
contract | нет | { number, date } — ссылка на договор, печатается в акте |
materials_info, attachment_note, currency, flow_type | нет |
/api/avr/create
← 200 { success, doc_id, flow_id, public_url, file_url, approver_links, total, total_words }
🧾 Счета-фактуры
Собирает обычную бумажную/PDF «Счёт-фактуру» — бухгалтерский документ с разбивкой НДС по позициям и подписями руководителя/главного бухгалтера поставщика — это не электронная ЭСФ через esf.gov.kz (см. раздел «ИС ЭСФ — документы (электронные ЭСФ/эАВР)» ниже для того случая). Реквизиты поставщика подтягиваются из companies по company_id, рендерится PDF и запускается внутреннее согласование (например руководитель → гл. бухгалтер) — тонкая обёртка над /api/approval/start, аналогично /api/invoice/create.
| Поле | Обязательно | Описание |
|---|---|---|
company_id | да | Компания-поставщик |
number, date | да | Номер и дата счёта-фактуры |
buyer | да | { name, bin?, address? } — получатель (покупатель) |
items | да | [{ name, unit?, qty?, price, vat_rate? }], минимум 1 — vat_rate долей, напр. 0.12; 0 или не указано — без НДС |
approvers | да | тот же формат, что в /approval/start — внутреннее согласование перед отправкой покупателю |
contract, director_name, chief_accountant_name, currency | нет | director_name/chief_accountant_name печатаются в строках подписи |
/api/schet-faktura/create
← 200 { success, doc_id, flow_id, public_url, file_url, approver_links, total, total_no_vat, total_vat, total_words }
🔐 ИС ЭСФ (esf.gov.kz) — сессия
Подключение компании к esf.gov.kz: билет подписывается ЭЦП на клиенте (NCALayer), приватный ключ на сервер не попадает.
Шаг 1: получить билет на подпись.
| Поле | Обязательно |
|---|---|
company_id | да |
iin | да — ИИН подписанта, 12 цифр |
environment | нет — test | prod (default prod) |
/api/esf/session/ticket
← 200 { success, auth_ticket_xml, environment }
Шаг 2: отправить билет, подписанный через NCALayer.signXml, — открывает сессию.
| Поле | Обязательно |
|---|---|
company_id, tin, signed_auth_ticket | да |
business_profile_type, environment | нет |
← 200 { success, session_id, environment }
Текущее состояние подключения компании.
← 200 { connected, status, live_status, session_id, tin, environment }
🔄 ИС ЭСФ — синхронизация с 1С
1С отправляет ЭСФ/АВР в esf.gov.kz своими кредами интегратора и пушит сюда копию/статус — единое окно DocHub, не дожидаясь собственной регистрации DocHub интегратором. См. integrations/1c/DocHubИнтеграция.bsl.
Приём факта/статуса отправки ЭСФ или АВР от 1С. Токен (не общий DOCHUB_API_KEY — свой на компанию) сам определяет, к какой компании относится документ.
| Поле | Обязательно | Описание |
|---|---|---|
doc_type | да | invoice (ЭСФ) | avr (эАВР) |
direction | да | outgoing | incoming |
counterparty_tin | да | |
external_id | нет | GUID документа в 1С — повторный вызов с тем же id обновляет статус, не дублирует |
esf_reg_number, status, amount, currency, doc_date, contract_number, error_message | нет |
/api/esf/sync
← 200 { success, id }
Получить (GET, создаёт при отсутствии) или перевыпустить (POST) токен компании для настройки 1С.
← 200 { success, token }
🗂️ ИС ЭСФ — документы (электронные ЭСФ/эАВР)
Создание и подпись электронных ЭСФ/эАВР для последующей передачи в esf.gov.kz — не путать с обычным печатным актом из раздела «Акты выполненных работ (АВР)» выше. Сама передача в esf.gov.kz — не отсюда: подписанный документ забирает 1С клиента через мост-интеграцию.
Список документов компании — реестр «ЭСФ и АВР» в интерфейсе.
← 200 { success, documents: [...] }
Собрать черновик ЭСФ или АВР. Суммы (без НДС / НДС / с НДС) считаются на сервере по позициям.
| Поле | Обязательно | Описание |
|---|---|---|
company_id | да | |
doc_type | да | invoice (ЭСФ) | avr (эАВР) |
counterparty_tin | да | |
items | да | [{ name, unit?, qty, price, vat_rate? }] — vat_rate долей, напр. 0.12 |
counterparty_name, contract_number, contract_date, doc_date, currency | нет |
/api/esf/documents/create
← 200 { success, document } // status: "draft"
Подписать черновик. signed_xml получают на клиенте через NCALayer.signXml над XML из buildEsfSigningXML() (utils/ncalayer.js) — в подпись входят реальные позиции и суммы, не только факт существования документа.
| Поле | Обязательно |
|---|---|
document_id | да |
signed_xml | да |
actor_id | нет |
← 200 { success, document } // status: "draft" → "signed"
🔀 Процессы (BPM-движок)
Один движок для согласования, поручений и ознакомления — процесс собирается визуальным редактором как граф (узлы: задача, условие, параллель, цикл, уведомление), а не заводится кодом на каждый случай.
GET ?company_id= — список; GET ?id= — одно определение; POST — создать { company_id, name, doc_type?, graph }; PUT — обновить граф по { id, graph } (версия инкрементируется).
Запустить процесс на документе.
| Поле | Обязательно |
|---|---|
definition_id, company_id | да |
document_id, context, started_by | нет — context доступен условиям процесса |
/api/bpm/start
← 200 { success, instance }
Завершить шаг «задача» — { instance_id, node_id, action: "approve"|"decline", actor_id }.
Подтвердить «ознакомление» — { instance_id, node_id, actor_id }.
Путь одного документа по процессу — вся история шагов.
Список запущенных/завершённых процессов компании — экран «Мониторинг».
Активные задачи и ознакомления конкретного пользователя.
🔎 Проверка контрагента по БИН/ИИН
Проверка по официальным сервисам КГД и автозаполнение названия при регистрации, добавлении контакта и заполнении профиля компании. Отдельный экран — «Контрагент 360°». Этот API также можно использовать для заполнения реквизитов в своей интеграции. Адрес и банковские реквизиты эти источники не возвращают: их нужно заполнить отдельно.
С risk=1 возвращает дашборд: financials (налоги, работники и КНН за пять календарных лет), assessment (налоговые сигналы DocHUB), procurement (карточка госзакупок), compliance.checks (расширенные реестры КГД) и sources. В комплаенс входят ликвидация, ОВД, отдельный реестр налоговых режимов, события и объявления банкротства, решения о реабилитации/банкротстве/ликвидации, прекращение реабилитации и требования кредиторов, публичный перечень ограничений выписки ЭСФ. Статусы независимы: checked, unavailable, access_denied, not_configured, partial; found:null — результат не получен. Исторические записи не подтверждают текущее ограничение. Полный список судебных дел, взыскания, РНУ, лицензии и перечни АФМ остаются ручными источниками.
Работает без входа в DocHUB и без X-Api-Key. Токен КГД хранится только на сервере. Проверяет контрольную сумму и ищет налогоплательщика, включая компании без записи в реестре НДС. risk=1 добавляет сведения о неблагонадёжности, признаки риска и сумму задолженности из открытых данных с датой их актуальности. «Нет данных» означает отсутствие сведений, а не положительный результат проверки.
| Параметр | Обязательно | Описание |
|---|---|---|
code | да | БИН или ИИН, 12 цифр |
type | нет | AUTO (по умолчанию), UL (юрлицо), IP (ИП), FL (физлицо), UL_NR, LZCHP. При регистрации выбирайте ТОО/АО или ИП. |
risk | нет | 1 — добавить отчёт «Контрагент 360°» в поле risk |
/api/counterparty/lookup?risk=1&code=...
← 400 { success:false, valid:false, reason:"length"|"checksum", message }
← 200 { success:true, valid:true, code, source:"local", found:null, registry:{status:"not_configured"} }
← 200 { success:true, valid:true, code, source:"kgd", found:true, name, name_kz,
registry:{status:"found", registration_date, taxpayer_type},
checked_at, cached, actuality, activity:{code,name}, tax_regime, tax_regime_since,
vat:{status:"checked"|"not_found"|"unavailable", is_payer:true|false|null},
risk?: { unreliable_taxpayer:{status, is_unreliable, categories}, indicators:[{code,title,value,status}],
tax_debt:{status, source, actuality, has_debt, total_arrear, currency:"KZT"} } }
← 429 { error:"RATE_LIMITED" }
found:false — запись не найдена; found:null — результат не получен. Проверяйте registry.status и статусы отдельных источников. Ответы могут быть частичными. Кэш успешного поиска — до 5 минут, частичного — 15 секунд; checked_at сохраняет время проверки. Лимит — 30 запросов в минуту на IP.
compliance: { checked_at, checks: [{ id, title, status, found, count,
records:[{title,date,detail}], checked_at, url, note, neutral?, truncated? }] }
Общие реестры КГД кэшируются на 10 минут. Первый расширенный запрос может занимать до 55 секунд. Пустые, ошибочные и неполные ответы не превращаются в подтверждение отсутствия рисков.
Проверка по точному ИИН: регистрация ИП и записи неблагонадёжных налогоплательщиков, где КГД указал этот ИИН руководителя. Требуется авторизация пользователя компании или настроенная серверная интеграция. ФИО для поиска не используется. Наличие ИП не является негативным признаком. Связь с компанией вводится пользователем и не подтверждает текущие полномочия.
| Поле | Описание |
|---|---|
company_bin | БИН проверяемой компании, строка из 12 цифр |
iin | Точный ИИН руководителя, строка из 12 цифр с верной контрольной суммой |
relationship_basis | Обязательное значение user_provided |
relationship_reference | Необязательное основание связи, до 500 символов |
/api/counterparty/director← 200 { success:true, checked_at, company_bin, relation_status:"user_provided",
identity:{status:"registered"|"not_found"|"unavailable",name,registration_date,deregistration_date},
related_companies:{status:"checked"|"unavailable",companies:[{code,name,categories}],truncated}, note }
← 401 { error:"AUTH_REQUIRED" }
← 400 { error:"INVALID_BIN_IIN" }
← 429 { error:"RATE_LIMITED" }
Лимит 10 запросов на пользователя в минуту, 4 одновременно. ИИН отправляется в теле POST, результаты не кэшируются. Закрытый профиль физлица/КДП и персональное банкротство этим API не проверяются. Пустая первая страница реестра граждан не является полной проверкой.
🤖 ИИ-инструменты
Оцифровка документов и «Документ 360» (юридическая и финансово-налоговая проверка любого документа) через GPT — требует OPENAI_API_KEY на сервере (см. api/lib/aiProvider.js); без ключа оба эндпоинта отвечают 503. В приложении — раздел «Проверки и ИИ».
Извлекает структурированные поля из фото/PDF счёта, акта, счёта-фактуры или договора. Документ не создаётся — только данные для подстановки в форму создания.
| Поле | Обязательно | Описание |
|---|---|---|
file_base64 | да | Файл в base64, без data:...;base64, префикса |
mime_type | да | image/jpeg · image/png · image/webp · application/pdf |
hint | нет | Подсказка о типе документа |
← 200 { success:true, extracted:{ doc_type, number, date, counterparty:{name,bin_iin,address},
items:[{name,unit,qty,price}], total_amount, currency, confidence, notes } }
«Документ 360» — предварительный обзор ЛЮБОГО делового документа (договор, соглашение, NDA, меморандум, акт, счёт и т.п.) на юридическую И финансово-налоговую чистоту простым языком — не консультация юриста/бухгалтера (см. disclaimer в ответе). Принимает текст ИЛИ файл, не оба сразу.
| Поле | Обязательно | Описание |
|---|---|---|
text | да, если нет файла | Текст документа |
file_base64 + mime_type | да, если нет текста | application/pdf · image/jpeg · image/png · image/webp |
doc_type | нет | contract · agreement · nda · memorandum — подстраивает подсказки под тип документа (см. utils/documentTemplates.js DOC_TYPES); неизвестное или отсутствующее значение — общий обзор, тип определяется по тексту |
← 200 { success:true, summary, risk_level:"low"|"medium"|"high",
findings:[{severity,title,detail,clause_ref}], missing_clauses:[...],
financial_tax:{ status:"clean"|"attention"|"critical"|"not_applicable", summary, findings:[...] },
disclaimer }
🧩 Прочее
Адресная книга компании (внешние контакты — без аккаунта в DocHub). GET ?company_id=&q= — список/поиск; POST — создать { company_id, name, email?, phone?, iin_bin?, position?, note? }; PUT — обновить по { id, ... }; DELETE ?id=.
/api/contacts
Отдаёт файл из закрытого бакета вложений по временной подписанной ссылке Supabase (s обязан начинаться с /object/sign/) — сам внутренний адрес хранилища наружу не уходит.
Мобильная подпись — требуется настройка сервера
Только JWT пользователя, назначенного подписантом. X-Api-Key не подходит. Перед включением нужны SQL-миграция, локальный NCANode, проверенные политики доступа и проверка реальной ЭЦП. Без настройки API возвращает 503.
Проверяет пользователя, компанию, назначение и очередь. Документ должен содержать одно вложение до 10 МиБ. Подписанту заранее задаётся ИИН/БИН сертификата. Возвращает одноразовый запрос на 120 секунд, хэш оригинала, открытый RSA-ключ и AAD.
{"doc_id":"00000000-0000-4000-8000-000000000001"}
Ответ: challenge_id, doc_id, approver_id, title, file_name, file_sha256, expires_at, public_key_pem, algorithm, aad.
Мобильный клиент шифрует JSON {p12_base64,password} алгоритмом AES-256-GCM со случайным ключом (32 байта), IV (12 байт), тегом (16 байт). AAD — строка из challenge без изменений. AES-ключ шифруется RSA-OAEP с SHA-256/MGF1-SHA-256. Все бинарные поля кодируются стандартным Base64.
{
"challenge_id": "UUID из первого ответа",
"encrypted_key": "Base64 RSA-OAEP ciphertext",
"iv": "Base64 12 bytes",
"ciphertext": "Base64 encrypted JSON",
"tag": "Base64 16 bytes"
}
Эти значения — описание формата, не исполняемый пример. Используйте клиент приложения; не вставляйте P12 и пароль в публичную API-консоль. Лимит P12: 256 КиБ, пароль: 1024 байта UTF-8. Успех: {success, all_signed, doc_status, signature_id}.
После проверки доступа возвращает {doc_id,signatures:[]}: для каждой подписи — неизменяемый оригинал original_base64, cms, SHA-256, сведения сертификата и дата. P12 и пароль в ответе и БД отсутствуют. Оригинал + CMS пригодны для независимой проверки средствами, поддерживающими алгоритмы НУЦ РК.