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) и своей команды.

Значение хранится только в этом браузере (localStorage) и отправляется исключительно на doc-hub.net. Примеры создают настоящие документы — перед выполнением проверьте company_id и другие данные в теле запроса.

📘 Аутентификация

Два способа, для каждого запроса достаточно одного.

СпособЗаголовокДля кого
X-Api-KeyX-Api-Key: <ключ>Серверные интеграции (1С, CRM) — ключ конкретной компании, создаётся в её профиле (см. ниже). Работает и старый общий ключ (переменная DOCHUB_API_KEY) — для обратной совместимости, новым интеграциям он не нужен.
Bearer JWTAuthorization: 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>"

✍️ Согласование документов

Запуск и подписание маршрута согласования — договор, акт, любой файл.

POST/api/approval/startX-Api-KeyBearer

Создаёт документ, маршрут согласования, добавляет согласующих, загружает файл. multipart/form-data (с файлом) или application/json (без).

ПолеТипОбязательноОписание
titlestringдаНазвание документа
company_iduuidдаКомпания-инициатор
approversarrayда[{ user_id? | email, name?, iin_bin?, role, order_num, deadline? }] — role: approver | signer
filefileнетPDF/DOCX/XLSX/изображение, до 25 МБ
doc_typestringнетcontract (default) · act · invoice · nda · agreement · poa · order · other · avr · schet_faktura
flow_typestringнетsequential (default) · parallel
counterparty, amount, currency, doc_date, description—нетМетаданные документа

iin_bin у согласующего — сервер сверяет его с ИИН/БИН из сертификата ЭЦП при подписании и отклоняет чужую подпись (403 IIN_BIN_MISMATCH).

Пример запроса — отредактируйте и нажмите «Выполнить»
POST /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}" }]
}
POST/api/approval/signбез auth

Сохраняет подпись согласующего. Вызывается с публичной страницы /p/{docId}?t={token} — токен сам по себе и есть авторизация конкретного подписанта.

ПолеОбязательноОписание
sign_tokenда (приоритетно)Персональный токен подписанта
signed_xmlдаПодписанный XML от NCALayer
doc_idесли нет токенаUUID документа (запасной способ)
← 200 { success, approver_id, all_signed, doc_status }
GET/api/approval/file?id={docId}без auth

Публичная отдача оригинального файла документа — используется на странице подписания и в превью.

GET/api/approval/pdf?id={docId}без auth

Генерирует печатный PDF со штампом ЭЦП и QR-кодом после того, как документ подписан.

💵 Счета на оплату

POST/api/invoice/createX-Api-KeyBearer

Собирает «Счёт на оплату» из структурированных данных (реквизиты поставщика подтягиваются из 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
Пример запроса — отредактируйте и нажмите «Выполнить»
POST /api/invoice/create
← 200 { success, doc_id, flow_id, public_url, file_url, approver_links, total, total_words }

📋 Акты выполненных работ (АВР)

POST/api/avr/createX-Api-KeyBearer

Собирает обычный печатный «Акт выполненных работ (оказанных услуг)» по образцу официального бланка (Форма Р-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нет
Пример запроса — отредактируйте и нажмите «Выполнить»
POST /api/avr/create
← 200 { success, doc_id, flow_id, public_url, file_url, approver_links, total, total_words }

🧾 Счета-фактуры

POST/api/schet-faktura/createX-Api-KeyBearer

Собирает обычную бумажную/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 печатаются в строках подписи
Пример запроса — отредактируйте и нажмите «Выполнить»
POST /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), приватный ключ на сервер не попадает.

POST/api/esf/session/ticketX-Api-KeyBearer

Шаг 1: получить билет на подпись.

ПолеОбязательно
company_idда
iinда — ИИН подписанта, 12 цифр
environmentнет — test | prod (default prod)
Пример запроса — отредактируйте и нажмите «Выполнить»
POST /api/esf/session/ticket
← 200 { success, auth_ticket_xml, environment }
POST/api/esf/session/finishX-Api-KeyBearer

Шаг 2: отправить билет, подписанный через NCALayer.signXml, — открывает сессию.

ПолеОбязательно
company_id, tin, signed_auth_ticketда
business_profile_type, environmentнет
← 200 { success, session_id, environment }
GET/api/esf/session/status?company_id=&environment=X-Api-KeyBearer

Текущее состояние подключения компании.

← 200 { connected, status, live_status, session_id, tin, environment }

🔄 ИС ЭСФ — синхронизация с 1С

1С отправляет ЭСФ/АВР в esf.gov.kz своими кредами интегратора и пушит сюда копию/статус — единое окно DocHub, не дожидаясь собственной регистрации DocHub интегратором. См. integrations/1c/DocHubИнтеграция.bsl.

POST/api/esf/syncX-Api-Key токен компании

Приём факта/статуса отправки ЭСФ или АВР от 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нет
Пример запроса — вставьте токен компании выше и нажмите «Выполнить»
POST /api/esf/sync
← 200 { success, id }
GET/api/esf/sync-token?company_id=POST (перевыпуск)X-Api-KeyBearer

Получить (GET, создаёт при отсутствии) или перевыпустить (POST) токен компании для настройки 1С.

← 200 { success, token }

🗂️ ИС ЭСФ — документы (электронные ЭСФ/эАВР)

Создание и подпись электронных ЭСФ/эАВР для последующей передачи в esf.gov.kz — не путать с обычным печатным актом из раздела «Акты выполненных работ (АВР)» выше. Сама передача в esf.gov.kz — не отсюда: подписанный документ забирает 1С клиента через мост-интеграцию.

GET/api/esf/documents?company_id=&doc_type=&status=&direction=X-Api-KeyBearer

Список документов компании — реестр «ЭСФ и АВР» в интерфейсе.

← 200 { success, documents: [...] }
POST/api/esf/documents/createX-Api-KeyBearer

Собрать черновик ЭСФ или АВР. Суммы (без НДС / НДС / с НДС) считаются на сервере по позициям.

ПолеОбязательноОписание
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нет
Пример запроса — отредактируйте и нажмите «Выполнить»
POST /api/esf/documents/create
← 200 { success, document }  // status: "draft"
POST/api/esf/documents/signX-Api-KeyBearer

Подписать черновик. signed_xml получают на клиенте через NCALayer.signXml над XML из buildEsfSigningXML() (utils/ncalayer.js) — в подпись входят реальные позиции и суммы, не только факт существования документа.

ПолеОбязательно
document_idда
signed_xmlда
actor_idнет
← 200 { success, document }  // status: "draft" → "signed"

🔀 Процессы (BPM-движок)

Один движок для согласования, поручений и ознакомления — процесс собирается визуальным редактором как граф (узлы: задача, условие, параллель, цикл, уведомление), а не заводится кодом на каждый случай.

GET POST PUT/api/bpm/definitionsX-Api-KeyBearer

GET ?company_id= — список; GET ?id= — одно определение; POST — создать { company_id, name, doc_type?, graph }; PUT — обновить граф по { id, graph } (версия инкрементируется).

POST/api/bpm/startX-Api-KeyBearer

Запустить процесс на документе.

ПолеОбязательно
definition_id, company_idда
document_id, context, started_byнет — context доступен условиям процесса
Пример запроса — отредактируйте и нажмите «Выполнить»
POST /api/bpm/start
← 200 { success, instance }
POST/api/bpm/task/completeX-Api-KeyBearer

Завершить шаг «задача» — { instance_id, node_id, action: "approve"|"decline", actor_id }.

POST/api/bpm/ackX-Api-KeyBearer

Подтвердить «ознакомление» — { instance_id, node_id, actor_id }.

GET/api/bpm/instance?id=X-Api-KeyBearer

Путь одного документа по процессу — вся история шагов.

GET/api/bpm/instances?company_id=&status=X-Api-KeyBearer

Список запущенных/завершённых процессов компании — экран «Мониторинг».

GET/api/bpm/my-tasks?actor_id=X-Api-KeyBearer

Активные задачи и ознакомления конкретного пользователя.

🔎 Проверка контрагента по БИН/ИИН

Проверка по официальным сервисам КГД и автозаполнение названия при регистрации, добавлении контакта и заполнении профиля компании. Отдельный экран — «Контрагент 360°». Этот API также можно использовать для заполнения реквизитов в своей интеграции. Адрес и банковские реквизиты эти источники не возвращают: их нужно заполнить отдельно.

С risk=1 возвращает дашборд: financials (налоги, работники и КНН за пять календарных лет), assessment (налоговые сигналы DocHUB), procurement (карточка госзакупок), compliance.checks (расширенные реестры КГД) и sources. В комплаенс входят ликвидация, ОВД, отдельный реестр налоговых режимов, события и объявления банкротства, решения о реабилитации/банкротстве/ликвидации, прекращение реабилитации и требования кредиторов, публичный перечень ограничений выписки ЭСФ. Статусы независимы: checked, unavailable, access_denied, not_configured, partial; found:null — результат не получен. Исторические записи не подтверждают текущее ограничение. Полный список судебных дел, взыскания, РНУ, лицензии и перечни АФМ остаются ручными источниками.

GET/api/counterparty/lookup?code={БИН/ИИН}&risk=1без auth

Работает без входа в DocHUB и без X-Api-Key. Токен КГД хранится только на сервере. Проверяет контрольную сумму и ищет налогоплательщика, включая компании без записи в реестре НДС. risk=1 добавляет сведения о неблагонадёжности, признаки риска и сумму задолженности из открытых данных с датой их актуальности. «Нет данных» означает отсутствие сведений, а не положительный результат проверки.

ПараметрОбязательноОписание
codeдаБИН или ИИН, 12 цифр
typeнетAUTO (по умолчанию), UL (юрлицо), IP (ИП), FL (физлицо), UL_NR, LZCHP. При регистрации выбирайте ТОО/АО или ИП.
riskнет1 — добавить отчёт «Контрагент 360°» в поле risk
Пример запроса — впишите БИН/ИИН и нажмите «Выполнить»
GET /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 секунд. Пустые, ошибочные и неполные ответы не превращаются в подтверждение отсутствия рисков.

POST/api/counterparty/directorX-Api-KeyBearer

Проверка по точному ИИН: регистрация ИП и записи неблагонадёжных налогоплательщиков, где КГД указал этот ИИН руководителя. Требуется авторизация пользователя компании или настроенная серверная интеграция. ФИО для поиска не используется. Наличие ИП не является негативным признаком. Связь с компанией вводится пользователем и не подтверждает текущие полномочия.

ПолеОписание
company_binБИН проверяемой компании, строка из 12 цифр
iinТочный ИИН руководителя, строка из 12 цифр с верной контрольной суммой
relationship_basisОбязательное значение user_provided
relationship_referenceНеобязательное основание связи, до 500 символов
Заполните ИИН из подтверждённых реквизитов и ключ авторизации
POST/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. В приложении — раздел «Проверки и ИИ».

POST/api/ai/digitizeX-Api-KeyBearer

Извлекает структурированные поля из фото/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 } }
POST/api/ai/contract-reviewX-Api-KeyBearer

«Документ 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 }

🧩 Прочее

GET POST PUT DELETE/api/contactsX-Api-KeyBearer

Адресная книга компании (внешние контакты — без аккаунта в DocHub). GET ?company_id=&q= — список/поиск; POST — создать { company_id, name, email?, phone?, iin_bin?, position?, note? }; PUT — обновить по { id, ... }; DELETE ?id=.

Пример запроса — отредактируйте и нажмите «Выполнить»
POST /api/contacts
GET/api/storage/file?s=&name=подписанный путь

Отдаёт файл из закрытого бакета вложений по временной подписанной ссылке Supabase (s обязан начинаться с /object/sign/) — сам внутренний адрес хранилища наружу не уходит.

Мобильная подпись — требуется настройка сервера

Только JWT пользователя, назначенного подписантом. X-Api-Key не подходит. Перед включением нужны SQL-миграция, локальный NCANode, проверенные политики доступа и проверка реальной ЭЦП. Без настройки API возвращает 503.

POST/api/mobile-signing/challengeBearer JWT

Проверяет пользователя, компанию, назначение и очередь. Документ должен содержать одно вложение до 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.

POST/api/mobile-signing/signBearer JWT

Мобильный клиент шифрует 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}.

Создаётся отдельная CMS-подпись оригинальных байтов, не визуальный штамп и не встроенная PAdES-подпись PDF. RAM не гарантирует юридическое соответствие или мгновенное физическое стирание: JavaScript/JVM, swap и дампы требуют отдельного контроля.
GET/api/mobile-signing/evidence?doc_id=UUIDBearer JWT

После проверки доступа возвращает {doc_id,signatures:[]}: для каждой подписи — неизменяемый оригинал original_base64, cms, SHA-256, сведения сертификата и дата. P12 и пароль в ответе и БД отсутствуют. Оригинал + CMS пригодны для независимой проверки средствами, поддерживающими алгоритмы НУЦ РК.