Готовые сценарии
Готовый копируемый код под пять реальных сценариев — импорт из Китая, ЭДО, чертежи, приемка поставки, разбор архива договоров.
Сценарии ниже разобраны на странице кейсов
с измеренными результатами на реальных документах — здесь тот же материал в
формате «скопировал — запустил». Все примеры используют один эндпоинт
/v1/process; принципы проектирования схемы — в
«output_schema».
То же самое без кода
Первые сценарии целиком повторяются в кабинете мышкой: тип документа → колонки → файл → Excel, без единой строки кода — см. «Кабинет и обработка без кода».
Упаковочный лист из Китая → Excel с переводом
Задача. Поставщик присылает packing list на китайском, а нужен русский Excel: реквизиты отгрузки, таблица позиций с наименованиями по-русски и весами — чтобы свести с заказом и отдать на склад.
Три поля отвечают за весь сценарий: language=zh (без него иероглифы на
скане не распознаются), translate={"to":"ru"} — перевод строковых значений
result после извлечения, и format=xlsx при заборе результата. Перевод
требует непустую output_schema, иначе TRANSLATE_REQUIRES_SCHEMA (422).
TASK=$(curl -s -X POST https://api.docinspect.ru/v1/process \
-H "X-API-Key: $API_KEY" \
-F "file=@packing_list.pdf" \
-F "document_type=packing_list" \
-F "language=zh" \
-F 'translate={"to":"ru"}' \
-F "async=true" \
-F 'output_schema={
"type": "object",
"properties": {
"number": {"type": "string", "title": "Номер"},
"shipper": {"type": "string", "title": "Отправитель"},
"consignee": {"type": "string", "title": "Получатель"},
"gross_weight_total": {"type": "number", "title": "Брутто, кг"},
"items": {
"type": "array",
"title": "Позиции",
"items": {
"type": "object",
"properties": {
"article": {"type": "string", "title": "Артикул"},
"name": {"type": "string", "title": "Наименование"},
"quantity": {"type": "number", "title": "Количество"},
"unit": {"type": "string", "title": "Единица"},
"net_weight": {"type": "number", "title": "Нетто, кг"}
}
}
}
}
}' | jq -r .task_id)async=true здесь не формальность: скан упаковочного листа проходит OCR и
перевод, а внешний прокси рвет синхронное соединение на 300 секундах.
Поллинг — тем же ключом, пока status не станет done:
curl -s https://api.docinspect.ru/v1/process/$TASK -H "X-API-Key: $API_KEY" | jq .status
# processing → done
curl -H "X-API-Key: $API_KEY" \
"https://api.docinspect.ru/v1/process/$TASK?format=xlsx" -o packing_list.xlsxПока status=processing, ?format=xlsx вернет тот же JSON, а не файл —
дожидайтесь done. JSON того же результата:
{
"result": {
"shipper": "深圳市华强电子有限公司",
"items": [{ "name": "不锈钢法兰 DN50 PN16", "quantity": 10, "unit": "个" }]
},
"translated": {
"to": "ru",
"result": {
"shipper": "Шэньчжэньская компания «Хуацян электроникс»",
"items": [{ "name": "Фланец из нержавеющей стали DN50 PN16", "quantity": 10, "unit": "шт." }]
}
},
"usage": { "pages": 2, "sheets": 2, "translation_tokens": 412 }
}title каждого свойства схемы становится заголовком колонки в Excel —
поэтому в примере они заполнены по-русски. Механика перевода и устройство
листов файла — в «/v1/process» → «Перевод и
Excel»; термины (единицы измерения, типы
упаковки, Инкотермс) закрывает глоссарий без обращения к модели.
Входящая первичка из ЭДО
Задача. Счета, акты и УПД приходят потоком от разных контрагентов, в разных шаблонах (где-то ИНН продавца в шапке, где-то — в таблице реквизитов). Нужно разложить по единым полям и сверить суммы, прежде чем документ уйдет в учетную систему.
curl -X POST https://api.docinspect.ru/v1/process \
-H "X-API-Key: $API_KEY" \
-F "file=@invoice-0148.pdf" \
-F "prompt=Извлеки реквизиты сторон, позиции и суммы счета. Поставщика и покупателя определяй по подписям «Поставщик»/«Покупатель», а не по порядку появления в документе" \
-F 'output_schema={
"type": "object",
"properties": {
"number": {"type": "string"},
"supplier": {"type": "object"},
"customer": {"type": "object"},
"items": {"type": "array"},
"total_amount": {"type": "number"}
}
}'{
"result": {
"number": "0148",
"supplier": { "name": "ООО «Балтмонтаж»", "inn": "7801234565", "kpp": "780101001" },
"customer": { "name": "ООО «Невский Провиант»", "inn": "7810998874", "kpp": "781001001" },
"items": [{ "service_type": "Термоусадочная пленка", "quantity": 40, "amount": 128000.0 }],
"total_amount": 153600.0
},
"usage": { "pages": 1, "sheets": 1 },
"metadata": { "extraction_status": "full", "cached": false, "…": "…" },
"warnings": []
}Расхождение итога со строками не нужно ловить самому: если сумма документа
не сходится с позициями, в ответе появится warning totals_mismatch (см.
«Ошибки»).
Когда промпт можно убрать
Если поток однотипный и роли сторон в бланках устойчивы, тот же вызов
работает и без prompt — одной output_schema. Это короче по времени
обработки; на нестандартных бланках промпт с явным правилом «как отличить
поставщика от покупателя» надежнее.
Конвейер проверки чертежей
Задача. Альбом чертежей по ГОСТ 2.106 нужно превратить в таблицу BOM (обозначения, наименования, количества) и сверить позиции с реестром снабжения, не сохраняя сам реестр на стороне API.
curl -X POST https://api.docinspect.ru/v1/process \
-H "X-API-Key: $API_KEY" \
-F "file=@gearbox.pdf" \
-F "prompt=Извлеки обозначение, масштаб и спецификацию (BOM) чертежа" \
-F 'include=["tables","fields"]' \
-F 'output_schema={
"type": "object",
"properties": {
"designation": {"type": "string"},
"scale": {"type": "string"},
"specification": {
"type": "array",
"items": {
"type": "object",
"properties": {
"position": {"type": "string"},
"designation": {"type": "string"},
"name": {"type": "string"},
"quantity": {"type": "integer"}
}
}
}
}
}'include: ["tables", "fields"] — то, ради чего чертежи вообще идут в API:
tables возвращает таблицу спецификации, собранную по линиям сетки
векторного слоя, а fields — provenance: страницу и координаты, где найдено
каждое значение. Обе секции доступны только для PDF.
{
"result": {
"designation": "МПСТ.01.00.00СБ",
"scale": "1:2",
"specification": [
{ "position": "1", "designation": "МПСТ.01.01.00СБ", "name": "Крышка смотрового отверстия", "quantity": 1 },
{ "position": "2", "designation": "МПСТ.01.02.00СБ", "name": "Тихоходный вал", "quantity": 1 }
]
},
"tables": [{ "pages": [0], "markdown": "| Поз. | Обозначение | Наименование | Кол. |\n…" }],
"fields": [{ "name": "designation", "value": "МПСТ.01.00.00СБ", "page": 1, "level": "L1", "bbox": [612, 780, 742, 796] }],
"usage": { "pages": 8, "sheets": 1 }
}Лист формата А1 — это восемь тарифицируемых страниц при одном физическом
листе; usage показывает оба числа, чтобы счет не выглядел ошибкой (см.
«Квоты и биллинг»).
Там, где спецификация нарисована кривыми, а не набрана текстом, подключается OCR по вырезанной области листа — на контракт ответа это не влияет.
Приемка поставки
Задача. Груз приходит с накладной ЦМР/ТТН и упаковочным листом — до подписания приемки нужно свести вес нетто и брутто, количество мест и позиции с заказом, а позиции еще и проверить по реестру снабжения.
curl -X POST https://api.docinspect.ru/v1/process \
-H "X-API-Key: $API_KEY" \
-F "file=@cmr-4471.pdf" \
-F "prompt=Извлеки стороны, груз и вес по накладной ЦМР/ТТН" \
-F 'output_schema={
"type": "object",
"properties": {
"cmr_number": {"type": "string"},
"sender": {"type": "object"},
"consignee": {"type": "object"},
"cargo": {"type": "object"},
"gross_weight_kg": {"type": "number"},
"net_weight_kg": {"type": "number"}
}
}'{
"result": {
"cmr_number": "4471/1",
"sender": { "name": "ООО «Стальпром»", "country": "RU" },
"consignee": { "name": "ООО «Балтийский склад»", "country": "RU" },
"cargo": { "packages_count": 18, "description": "Металлопрокат, паллеты" },
"gross_weight_kg": 412,
"net_weight_kg": 380
},
"usage": { "pages": 1, "sheets": 1 },
"warnings": []
}Инвариант «нетто ≤ брутто» проверяется на сервере: если в документе веса перепутаны, ответ придет с предупреждением, а не с тихо принятыми значениями:
{
"warnings": [
{
"code": "weight_invariant_violation",
"field": "net_weight_kg",
"severity": "high",
"message": "net_weight_kg > gross_weight_kg"
}
]
}Позиции упаковочного листа сверяются с реестром снабжения тем же вызовом —
match и вторая file-part registry, отдельного запроса не нужно:
curl -X POST https://api.docinspect.ru/v1/process \
-H "X-API-Key: $API_KEY" \
-F "file=@packing-list.pdf" \
-F 'output_schema={"type":"object","properties":{"items":{"type":"array",
"items":{"type":"object","properties":{"article":{"type":"string"},
"quantity":{"type":"number"}}}}}}' \
-F 'match={"key_column":"ARTCL","values_from":"items[].article"}' \
-F "registry=@registry.csv"{
"result": { "items": [{ "article": "МПСТ.01.01.00СБ", "quantity": 1 }] },
"match": {
"found": 1,
"missing_in_registry": ["МПСТ.01.02.00СБ"],
"unmatched_registry": [],
"coverage": 0.5,
"registry_rows": 240,
"key_column": "ARTCL",
"values_field": "items[].article"
}
}Реестр обрабатывается в памяти запроса и не сохраняется. Если по правилам
компании он не должен покидать ее контур вовсе — та же сверка доступна SDK
docai-match на вашей стороне.
Подшивка документов поставки
Задача. Экспедитор прислал одним PDF всё, что ехало с грузом: транзитную декларацию, два электронных счёта, CMR, инвойсы и упаковочные листы — 13 страниц сканов на турецком, английском и русском. Нужно разложить их по документам и из каждого вытащить своё.
split: {"mode": "auto"} находит границы по титулам страниц (транзит,
e-Fatura, CMR, инвойс, упаковочный лист) и маркерам продолжения, каждой
секции ставит doc_type с номером. Со схемой из каждой секции сразу
извлекаются данные; language=tr подсказывает OCR и переводчику турецкий,
translate={"to":"ru"} переводит значения. Схема подшивки — общая: тип,
номер, дата, стороны, итог, вес, места и строки.
curl -X POST https://api.docinspect.ru/v1/process \
-H "X-API-Key: $API_KEY" \
-F "file=@shipment_pack.pdf" \
-F "language=tr" \
-F 'split={"mode":"auto"}' \
-F 'translate={"to":"ru"}' \
-F 'output_schema={
"type": "object",
"properties": {
"number": {"type": "string", "title": "Номер"},
"date": {"type": "string", "format": "date", "title": "Дата"},
"issuer": {"type": "string", "title": "Отправитель / продавец"},
"recipient": {"type": "string", "title": "Получатель / покупатель"},
"total": {"type": "number", "title": "Итого"},
"currency": {"type": "string", "title": "Валюта"},
"gross_weight_kg": {"type": "number", "title": "Брутто, кг"},
"packages_total": {"type": "number", "title": "Мест"}
}
}'{
"result": null,
"documents": [
{ "index": 1, "pages": [1, 2], "doc_type": "Транзитная декларация 24TR34120001542615", "result": { "packages_total": 5, "gross_weight_kg": 3870 }, "translated": { "to": "ru", "result": { "…": "…" } } },
{ "index": 2, "pages": [3, 3], "doc_type": "Транзитная декларация 24LR3412003297037", "result": { "…": "…" } },
{ "index": 3, "pages": [4, 4], "doc_type": "Инвойс RFF2024000000034", "result": { "total": 77882, "currency": "EUR" } },
{ "index": 5, "pages": [6, 6], "doc_type": "CMR", "result": { "…": "…" } },
{ "index": 7, "pages": [8, 9], "doc_type": "Упаковочный лист", "result": { "…": "…" } }
],
"usage": { "pages": 13, "sheets": 13 }
}Дальше каждая секция идёт своей дорогой: инвойс — в сверку с заказом,
упаковочный лист — на склад, декларация — брокеру. Если нужна не общая, а
своя схема на каждый тип, режьте без схемы (split без output_schema —
только границы и doc_type, без обращения к модели) и отправляйте секции
вторым вызовом с рецептом под тип: сплиттер отдаёт pdf_base64 каждой
секции при return_files: true.
Разбор архива договоров
Задача. Сшивка из договора и приложений в одном PDF на десятки-сотни страниц — архив нужно разложить на отдельные документы и извлечь условия, сроки и суммы по каждому, не упираясь в тайм-аут внешнего прокси.
Раньше это были два вызова — нарезка, затем извлечение по каждой секции.
Теперь это один запрос: split вместе с output_schema означает «разбей и
извлеки из каждого».
curl -X POST https://api.docinspect.ru/v1/process \
-H "X-API-Key: $API_KEY" \
-F "file=@lease-archive.pdf" \
-F "async=true" \
-F 'split={"mode":"auto"}' \
-F "prompt=Извлеки стороны, срок действия и сумму договора" \
-F 'output_schema={
"type": "object",
"properties": {
"title": {"type": "string"},
"parties": {"type": "array", "items": {"type": "object"}},
"valid_until": {"type": "string", "description": "YYYY-MM-DD"},
"total_amount": {"type": "number"}
}
}'{ "task_id": "a3f9c1e0", "poll_url": "/v1/process/a3f9c1e0" }async=true здесь обязателен: реальный скан на 138 страниц обрабатывается
около трех минут, а внешний прокси рвет соединение на 300 секундах.
Поллинг — тем же ключом:
curl https://api.docinspect.ru/v1/process/a3f9c1e0 -H "X-API-Key: $API_KEY"{
"task_id": "a3f9c1e0",
"status": "done",
"result": {
"result": null,
"documents": [
{ "index": 1, "pages": [1, 24], "doc_type": "Договор аренды № 118-СТ", "confidence": 0.94,
"result": { "title": "Договор аренды № 118-СТ", "valid_until": "2027-03-31", "total_amount": 2640000.0 } },
{ "index": 2, "pages": [25, 40], "doc_type": "Приложение 1. Спецификация", "confidence": 0.88,
"result": { "title": "Приложение 1. Спецификация оборудования", "total_amount": null } }
],
"usage": { "pages": 40, "sheets": 40 },
"metadata": { "extraction_status": "full", "…": "…" }
},
"error": null
}Верхний result при split — null, данные лежат в documents[]; расход
считается по всему файлу разом. Нужны сами PDF-секции (например, чтобы
разложить архив по папкам) — добавьте split={"mode":"auto","return_files":true},
и в каждом элементе появится pdf_base64. По умолчанию это выключено, чтобы
ответ не раздувался мегабайтами.
Чтобы потом сослаться на конкретный пункт договора, закажите
include=["fragments"] — фрагменты приходят с номерами страниц, и ответ
ассистента можно проверить, открыв страницу оригинала (см.
«fragments»).