Версия: v2.1 (расширяет v1, полностью совместима «снизу вверх»)
Аудитория: разработчики на стороне лаборатории/интегратора (REST).
Назначение: единая инструкция «с нуля до первого результата» — как подключиться, авторизоваться, забрать заявку из очереди клиники и вернуть результат анализа.
Что нового в v2.1. Эндпоинт
POST /result-valuesнаучился принимать три необязательных поля: человекочитаемоеtitle, нормуreference_rangeи отметку отклоненияflag. Если их не передавать — поведение не отличается от v1. Ни один URL, ни один обязательный параметр не менялись, миграция интеграции не требуется. Подробности — в разделе 6.1.Документ обезличен. Все секреты, имена сервисов, домены клиник и идентификаторы заявок приведены как плейсхолдеры:
{service_name},{rest_api_key},{billing_authkey},{clinic_host},{request_id},{analyze_id}. Реальные значения выдаются при онбординге.
| Плейсхолдер | Что это | Где используется |
|---|---|---|
{service_name} | Идентификатор вашего сервиса-провайдера | Заголовок X-SERVICE-NAME |
{rest_api_key} | REST-ключ Provider API | Заголовок X-SERVICE-REST-API-KEY |
{billing_authkey} | Ключ для billing-api (получение списка доменов) | GET lab-domains/{billing_authkey} |
{clinic_host} | Хост конкретной клиники (CRM-инстанс) | Базовый URL всех вызовов Provider API |
{request_id} | ID заявки на исследование | Тело запросов take/waiting/result-* |
{analyze_id} | ID анализа внутри заявки | Тело запросов result-* |
Заявка (request) — единица работы: один питомец, один провайдер, набор анализов. Анализ (analyze) — отдельная позиция внутри заявки. Результат отправляется по каждому анализу отдельно; когда заполнены все анализы заявки — заявка переходит в done.
Для интеграции используются два разных ключа:
{billing_authkey} — выдаётся billing-сервисом. Нужен только для того, чтобы получить список клиник (хостов), подключивших вашу лабораторию.{rest_api_key} — REST-ключ вашего сервиса. Используется во всех вызовах Provider API вместе с {service_name}.Оба ключа и {service_name} выдаются при онбординге. Храните их как секреты, не публикуйте в репозиториях и клиентских приложениях.
2.1. Получение списка доменов клиник
Перед вызовом Provider API нужно узнать, на каком {clinic_host} работать. Список доступных вам клиник возвращает billing-api:
GET https://{billing_host}/lab-domains/{billing_authkey}
Ответ — перечень доменов клиник, которые подключили вашу лабораторию и активировали интеграцию. Каждый элемент содержит хост клиники, который далее подставляется как {clinic_host}.
{
"success": true,
"data": [
{ "host": "{clinic_host}", "title": "..." }
// ...другие клиники
]
}
Выбор
{clinic_host}: дальнейшая работа (list → take → result) ведётся отдельно по каждой клинике. Заявки одной клиники недоступны под хостом другой.
Все запросы к Provider API авторизуются двумя HTTP-заголовками:
X-SERVICE-NAME: {service_name}
X-SERVICE-REST-API-KEY: {rest_api_key}
Базовый URL для всех эндпоинтов:
https://{clinic_host}/rest/api/provider-lab-requests/...
Если хотя бы один заголовок отсутствует или ключ неверный — 401 UNAUTHORIZED. Если для клиники не подключён тариф/аддон или не включена интеграция — ответ маскируется под 404 NOT_FOUND (см. раздел 8).
lab-domains → получить список {clinic_host}
│
▼
GET list → увидеть очередь заявок клиники (taken/tranzit/waiting)
│
▼
POST take → взять заявку в работу: taken → tranzit
│
▼
POST waiting (опц.) → пометить «ожидаем результат»: tranzit → waiting
│
▼
POST result-html → отправить результат по анализу
или result-values (повторять для каждого analyze_id заявки)
│
▼
когда заполнены все анализы → заявка автоматически переходит в done
Минимальный happy path: list → take → result-*. Шаг waiting нужен, когда результат готовится не сразу (длинная аналитика): он явно фиксирует, что заявка взята и ожидает результата.
| Статус | Значение | Виден в list? |
|---|---|---|
taken | Создана клиникой, ещё не взята провайдером | Да |
tranzit | Взята провайдером в работу (take) | Да |
waiting | Ожидает результата (waiting) | Да |
done | Все анализы заполнены — завершена | Нет |
cancelled / deleted / error | Терминальные | Нет (для провайдера = «не найдена») |
Правила переходов:
take: taken → tranzit. Идемпотентен — повторный вызов для заявки в tranzit или waiting вернёт текущий статус без ошибки. Для done → 409 ALREADY_TAKEN. Других целевых статусов у take нет — из taken можно попасть только в tranzit.waiting: tranzit → waiting. Идемпотентен для waiting. Из taken или done → 409 INVALID_STATUS_TRANSITION (сначала нужно take). Других переходов в waiting нет — попасть в этот статус можно только из tranzit.result-html/result-values) принимаются только из tranzit или waiting. Из других статусов → 409 INVALID_STATUS_TRANSITION.done не вызывается отдельным эндпоинтом — он выставляется автоматически, как только заполнен последний анализ заявки. Шаг waiting для этого не обязателен: заявка может дойти до done напрямую из tranzit (если результаты отправлены без промежуточной пометки ожидания) либо из waiting. Итоговый путь всегда один из двух: tranzit → done или tranzit → waiting → done.done гарантированно имеет все свои analyze_id заполненными (это и есть условие перехода в done). Поэтому повторная отправка результата по любому анализу такой заявки всегда вернёт 409 ALREADY_FILLED, а не 409 INVALID_STATUS_TRANSITION — проверка «анализ уже заполнен» выполняется раньше проверки статуса заявки. На практике INVALID_STATUS_TRANSITION для результатов возникает только у заявки в статусе taken (в ней по определению нет заполненных анализов, так как заполнение возможно лишь из tranzit/waiting).404 NOT_FOUND.Результат по анализу можно отправить в одном из двух форматов:
result-html — готовый HTML-фрагмент (например, отрендеренный бланк/таблица результатов). Подходит, когда лаборатория формирует визуальное представление сама.result-values — структурированный набор «параметр → значение → ед. измерения». Подходит для машиночитаемых показателей.Важно: формат фиксируется за заявкой по первому результату. Если первый результат отправлен как html, остальные анализы этой же заявки тоже должны идти html (и наоборот). Смешение → 409 INCOMPATIBLE_RESULT_FORMAT.
Оба формата поддерживают необязательные поля file_link, measured_at, comment.
6.1. Нормы и отметка отклонения — новое в v2.1
Раньше result-values отдавал плоскую таблицу «показатель / значение / единица», а название показателя печаталось техническим кодом (UREA вместо «Мочевина»), потому что сервер приводит name к верхнему регистру для внутреннего ключа. Врачу приходилось самому держать в голове нормы и искать отклонение глазами.
В v2.1 у каждого элемента values появились три необязательных поля:
| Поле | Тип | Что даёт |
|---|---|---|
title | string | Человекочитаемое название показателя для таблицы результата. name при этом остаётся техническим ключом и никуда не делся — он по-прежнему уходит в историю показателей |
reference_range | object | Норма показателя — числовая или текстовая (см. ниже) |
flag | string | Отметка отклонения, если её нельзя вычислить автоматически (см. «Кто выставляет отметку» ниже) |
Все три поля опциональны и независимы друг от друга. Можно прислать только title, только reference_range, всё вместе или ничего — как раньше.
6.1.1. title — человекочитаемое название
{ "name": "UREA", "title": "Мочевина", "value": "9.1", "unit": "ммоль/л" }
Если title не прислан — в таблице, как и раньше, печатается name. Ограничение:
не длиннее 255 символов.
6.1.2. reference_range — норма
Норма прикладывается к конкретному показателю и бывает трёх видов:
| Вид нормы | Как передаётся | Пример | Как отображается |
|---|---|---|---|
| Двусторонний интервал | min и max | { "min": 2.5, "max": 8.32 } | 2.5 – 8.32 |
| Односторонний | только minили только max | { "max": 100 } | до 100 |
{ "min": 57 } | от 57 | ||
| Качественная (текстовая) | text | { "text": "не обнаружено" } | не обнаружено |
Норму присылает провайдер и только он. Референс зависит от вида животного, возраста, пола, прибора и метода — всё это лаборатория знает о конкретном пациенте лучше клиники. Кстати, вид, порода, пол, дата рождения и вес питомца уже приходят провайдеру в ответе GET /list (раздел 7.1) —
именно для того, чтобы можно было подобрать нужный интервал перед отправкой
результата.
Правила валидации (нарушение → 400 INVALID_PAYLOAD с указанием, в каком показателе проблема):
min и max — числа, разделитель дробной части — точка.text вместе с min/max — норма либо числовая, либо текстовая.min не может быть больше max.text — не длиннее 100 символов.reference_range не может быть пустым объектом {} — если нормы нет, просто не передавайте поле вовсе.Если норма не прислана ни у одного показателя заявки — колонка «Норма» в таблице результата не появляется вообще, таблица остаётся трёхколоночной, как в v1. Это относится ко всей заявке целиком, не построчно: если норму передали хотя бы у одного показателя, колонка появляется для всех строк — просто у показателей без нормы она будет пустой.
6.1.3. flag — отметка отклонения
Допустимые значения: normal, low, high, critical_low, critical_high, abnormal. Любое другое значение — ошибка 400 INVALID_PAYLOAD, а не молчаливое
игнорирование.
critical_low / critical_high — это панические результаты (калий, глюкоза, лактат и подобные), при которых лаборатория обязана немедленно связаться с врачом. В таблице они выделяются заметнее обычного отклонения, поэтому передавайте их осознанно, а не «на всякий случай».
6.1.4. Кто выставляет отметку отклонения
Сервер сам считает отметку везде, где это возможно, и подставляет присланный flag только там, где вычислить нечем:
min → low, выше max → high, иначе normal. Присланный flag при этом игнорируется — кромеcritical_low/critical_high: критичность по границам не вычисляется, её знает только лаборатория, поэтому такой flag побеждает вычисленное значение."< 5" или "следы"). Норма в таблице показывается, но отметку сервер не ставит — что означает «< 5» относительно интервала, он решать не должен. Если нужна отметка — пришлите flag явно.flag не прислан. Сервер сравнивает value с текстом нормы (без учёта регистра и пробелов по краям): совпало → normal, не совпало → abnormal.flag прислан. Побеждает flag. Это нужно для шкал, где строковое сравнение врёт: норма «единичные в поле зрения», результат «3–4 в поле зрения» — строки не совпадают, но это не отклонение. Такую логику знает только интегратор.6.1.5. Примеры на каждый случай
Двусторонняя норма, отклонение сервер посчитает сам:
{ "name": "UREA", "title": "Мочевина", "value": "9.1", "unit": "ммоль/л",
"reference_range": { "min": 2.5, "max": 8.32 } }
Односторонняя норма («до 100»):
{ "name": "ALT", "title": "АЛТ", "value": "112", "unit": "Ед/л",
"reference_range": { "max": 100 } }
Качественный результат — сервер сам сравнит строки и поставит отклонение:
{ "name": "DIRO_AG", "title": "Дирофиляриоз, антиген", "value": "обнаружено",
"reference_range": { "text": "не обнаружено" } }
Шкала, где строковое сравнение обмануло бы — побеждает присланный flag:
{ "name": "URINE_WBC", "title": "Лейкоциты в осадке мочи", "value": "3–4 в п/з",
"reference_range": { "text": "единичные в поле зрения" },
"flag": "normal" }
Критическое значение — панический порог по границам не вычислить:
{ "name": "K", "title": "Калий", "value": "8.2", "unit": "ммоль/л",
"reference_range": { "min": 3.5, "max": 5.8 },
"flag": "critical_high" }
Без новых полей — как в v1, ничего не меняется:
{ "name": "HEMOLYSIS", "value": "отсутствует" }
Так делать нельзя — текстовая и числовая норма одновременно, 400 INVALID_PAYLOAD:
{ "name": "GLU", "value": "5.4",
"reference_range": { "min": 3.3, "text": "норма" } }
6.1.6. Как это выглядит в медкарте
Ниже — два реальных скриншота карточки медкарты (не макет), полученные одним и тем же запросом POST /result-values с разным набором полей.
Без title/reference_range/flag (как в v1, если ничего не менять): таблица остаётся трёхколоночной, показатель печатается техническим кодом (GLU, AST).

С title, reference_range и flag (новое в v2.1): появляется колонка «Норма», у показателя печатается человекочитаемое название, отклонения выделены полужирным со стрелкой (↑/↓), критическое значение — двойной стрелкой и
красным цветом.

Оформление — рамки, отступы, серая шапка, числа по правому краю — верстается инлайн-стилями внутри HTML, который уходит в описание медкарты, поэтому одинаково переживает и редактор карточки, и печатную форму.
Общие правила:
Content-Type: application/json)."success": true. Ошибка: "success": false + error_code + messages[].7.1. GET /list — очередь заявок
Параметры строки запроса (все необязательные):
| Параметр | Тип | По умолчанию | Ограничения |
|---|---|---|---|
status | string | все из taken,tranzit,waiting | только одно из taken, tranzit, waiting |
limit | int | 50 | от 1 до 200 |
offset | int | 0 | ≥ 0 |
Запрос:
GET /rest/api/provider-lab-requests/list?status=taken&limit=50&offset=0
Host: {clinic_host}
X-SERVICE-NAME: {service_name}
X-SERVICE-REST-API-KEY: {rest_api_key}
Ответ 200:
{
"success": true,
"total": 1,
"data": {
"labanalysisrequest": [
{
"id": {request_id},
"status": "taken",
"sample_number": 12345,
"create_date": "2024-01-15 10:30:00",
"comment": "...",
"pet": {
"id": 0,
"alias": "...",
"type": "...",
"breed": "...",
"sex": "...",
"birthdate": "...",
"weight": "..."
},
"analyzes": [
{ "id": {analyze_id}, "code": "...", "title": "...", "filled": 0 }
]
}
]
}
}
total — общее число заявок по фильтру (для пагинации), независимо от limit/offset.analyzes[].filled — 1, если по анализу уже принят результат, иначе 0.7.2. POST /take — взять заявку в работу
Тело:
{ "request_id": {request_id} }
Ответ 200:
{
"success": true,
"messages": ["Request accepted"],
"data": { "request_id": {request_id}, "request_status": "tranzit" }
}
7.3. POST /waiting — пометить ожидание результата
Тело:
{ "request_id": {request_id} }
Ответ 200:
{
"success": true,
"messages": ["Request moved to waiting"],
"data": { "request_id": {request_id}, "request_status": "waiting" }
}
7.4. POST /result-html — результат в формате HTML
Тело:
| Поле | Тип | Обяз. | Ограничения |
|---|---|---|---|
request_id | int | да | > 0 |
analyze_id | int | да | анализ должен принадлежать заявке |
html | string | да | не пусто; ≤ 1 МБ; без <script>/<iframe>/on*=-атрибутов |
file_link | string | нет | URL только с разрешённого файлового хоста (см. 8) |
measured_at | string | нет | ISO 8601, напр. 2024-01-15T10:30:00+02:00 |
comment | string | нет | произвольный текст |
HTML дополнительно санитизируется на сервере (вырезаются неразрешённые теги и атрибуты). Разрешён ограниченный набор форматирующих тегов и таблиц.
Запрос:
POST /rest/api/provider-lab-requests/result-html
Host: {clinic_host}
Content-Type: application/json
X-SERVICE-NAME: {service_name}
X-SERVICE-REST-API-KEY: {rest_api_key}
{
"request_id": {request_id},
"analyze_id": {analyze_id},
"html": "<table><tr><td>Hemoglobin</td><td>140 g/L</td></tr></table>",
"measured_at": "2024-01-15T10:30:00+02:00",
"comment": "..."
}
Ответ 200:
{
"success": true,
"messages": ["Result saved"],
"data": {
"request_id": {request_id},
"analyze_id": {analyze_id},
"medcard_id": 0,
"is_all_filled": false,
"request_status": "waiting"
}
}
is_all_filled — true, когда это был последний незаполненный анализ заявки.request_status — станет done, как только is_all_filled = true.7.5. POST /result-values — структурированный результат
Тело:
| Поле | Тип | Обяз. | Ограничения |
|---|---|---|---|
request_id | int | да | > 0 |
analyze_id | int | да | анализ должен принадлежать заявке |
values | array | да | непустой массив объектов (см. ниже) |
file_link | string | нет | URL только с разрешённого файлового хоста |
measured_at | string | нет | ISO 8601 |
comment | string | нет | произвольный текст |
Каждый элемент values:
| Поле | Тип | Обяз. | Ограничения |
|---|---|---|---|
name | string | да | ≤ 255 симв.; приводится к верхнему регистру и остаётся техническим ключом истории показателей; уникален в пределах values |
value | string | да | ≤ 255 симв. |
unit | string | нет | ≤ 50 симв. |
title | string | нет | v2.1. ≤ 255 симв.; человекочитаемое название для таблицы (если не прислано — печатается name) |
reference_range | object | нет | v2.1.{ min?, max?, text? } — норма показателя, см. раздел 6.1.2 |
flag | string | нет | v2.1. одно из: normal, low, high, critical_low, critical_high, abnormal — см. раздел 6.1.3 |
Запрос (базовый вариант, как в v1 — работает без изменений):
POST /rest/api/provider-lab-requests/result-values
Host: {clinic_host}
Content-Type: application/json
X-SERVICE-NAME: {service_name}
X-SERVICE-REST-API-KEY: {rest_api_key}
{
"request_id": {request_id},
"analyze_id": {analyze_id},
"values": [
{ "name": "HGB", "value": "140", "unit": "g/L" },
{ "name": "WBC", "value": "8.5", "unit": "10^9/L" }
],
"measured_at": "2024-01-15T10:30:00+02:00"
}
Запрос (с нормами и названиями — новое в v2.1):
POST /rest/api/provider-lab-requests/result-values
Host: {clinic_host}
Content-Type: application/json
X-SERVICE-NAME: {service_name}
X-SERVICE-REST-API-KEY: {rest_api_key}
{
"request_id": {request_id},
"analyze_id": {analyze_id},
"values": [
{ "name": "HGB", "title": "Гемоглобин", "value": "140", "unit": "g/L",
"reference_range": { "min": 120, "max": 180 } },
{ "name": "WBC", "title": "Лейкоциты", "value": "8.5", "unit": "10^9/L",
"reference_range": { "min": 6, "max": 17 } },
{ "name": "K", "title": "Калий", "value": "8.2", "unit": "ммоль/л",
"reference_range": { "min": 3.5, "max": 5.8 }, "flag": "critical_high" }
],
"measured_at": "2024-01-15T10:30:00+02:00"
}
Ответ 200: структура идентична result-html (см. 7.4) — новые поля на форму ответа не влияют, они меняют только оформление таблицы в медкарте.
Формат тела ошибки одинаков для всех эндпоинтов:
{
"success": false,
"error_code": "NOT_FOUND",
"messages": ["Заявка не найдена"]
}
8.1. По HTTP-кодам
| HTTP | error_code | Когда возникает | Что делать |
|---|---|---|---|
401 | UNAUTHORIZED | Нет одного из заголовков или неверный {rest_api_key} | Проверить заголовки и ключ |
404 | NOT_FOUND | Аддон/интеграция выключены; провайдер не найден; заявка не найдена/в терминальном статусе; анализ не принадлежит заявке | Проверить статус заявки и настройки клиники (раздел 9) |
400 | INVALID_PAYLOAD | Невалидные/отсутствующие поля, нарушены длины/формат measured_at, недопустимый status/limit/offset. v2.1: сюда же попадают ошибки title (> 255 симв.), reference_range (текст с границами вместе, пустой объект, min > max, нечисловые min/max, text > 100 симв.) и неизвестное значение flag | Исправить тело/параметры |
400 | INVALID_HTML | В html есть запрещённые элементы/атрибуты | Убрать <script>/<iframe>/on*= |
400 | INVALID_FILE_LINK | file_link не URL или хост не из разрешённого списка | Использовать допустимый файловый хост |
400 | DUPLICATE_KEYS | Повтор name внутри values | Сделать ключи уникальными |
409 | ALREADY_TAKEN | take для уже завершённой (done) заявки | Заявка закрыта, действий не требуется |
409 | INVALID_STATUS_TRANSITION | Недопустимый переход (waiting из taken/done; результат — из taken). Для заявки в done вместо этого кода приходит ALREADY_FILLED (см. ниже) | Привести заявку к нужному статусу (take → waiting) |
409 | INCOMPATIBLE_RESULT_FORMAT | Смешение html и values в одной заявке | Использовать формат первого результата |
409 | ALREADY_FILLED | По анализу результат уже отправлен, в т.ч. любой повторный результат по завершённой (done) заявке — все её анализы гарантированно заполнены, и эта проверка выполняется раньше проверки статуса | Не отправлять повторно |
8.2. Особый случай: 200 + total = 0
GET /list вернул success: true, но total: 0 и пустой labanalysisrequest. Это не ошибка авторизации — ключи приняты. Причины:
status;{clinic_host} идёт запрос;Проверьте: правильный ли {clinic_host}, создана ли заявка на провайдера, включена ли
интеграция per-клиника.
Чтобы заявки клиники стали видны через Provider API, на стороне клиники должны выполняться все условия:
{service_name}) → переключатель «Вкл». Технически это глобальный флаг сервиса (service.{service_name}) и per-клиника флаг интеграции — один и тот же тумблер на экране ниже.
taken. Заявка создаётся из карточки приёма/медкарты («Взятие анализа» → «Создать анализ»): сотрудник клиники указывает питомца, провайдера и нужные анализы из каталога, привязанного к этому провайдеру.
Если интеграция выключена или заявок нет — провайдер увидит 404 NOT_FOUND на адресные операции и total = 0 в list.
Готовая коллекция: provider-api-v1.postman_collection.json.
Импортируйте коллекцию и задайте переменные окружения (Environment):
| Переменная | Значение |
|---|---|
clinic_host | хост клиники (без протокола), например {clinic_host} |
service_name | {service_name} |
rest_api_key | {rest_api_key} |
billing_host | хост billing-api |
billing_authkey | {billing_authkey} |
request_id | ID заявки для take/waiting/result |
analyze_id | ID анализа для result |
Секреты в коллекцию не зашиты — все значения берутся из переменных окружения.
# 0. Список доменов клиник
curl -s "https://{billing_host}/lab-domains/{billing_authkey}"
# 1. Очередь заявок клиники
curl -s "https://{clinic_host}/rest/api/provider-lab-requests/list?status=taken&limit=50" \
-H "X-SERVICE-NAME: {service_name}" \
-H "X-SERVICE-REST-API-KEY: {rest_api_key}"
# 2. Взять заявку в работу
curl -s -X POST "https://{clinic_host}/rest/api/provider-lab-requests/take" \
-H "X-SERVICE-NAME: {service_name}" \
-H "X-SERVICE-REST-API-KEY: {rest_api_key}" \
-H "Content-Type: application/json" \
-d '{"request_id": {request_id}}'
# 3. (опционально) Пометить ожидание результата
curl -s -X POST "https://{clinic_host}/rest/api/provider-lab-requests/waiting" \
-H "X-SERVICE-NAME: {service_name}" \
-H "X-SERVICE-REST-API-KEY: {rest_api_key}" \
-H "Content-Type: application/json" \
-d '{"request_id": {request_id}}'
# 4a. Результат в формате HTML
curl -s -X POST "https://{clinic_host}/rest/api/provider-lab-requests/result-html" \
-H "X-SERVICE-NAME: {service_name}" \
-H "X-SERVICE-REST-API-KEY: {rest_api_key}" \
-H "Content-Type: application/json" \
-d '{
"request_id": {request_id},
"analyze_id": {analyze_id},
"html": "<table><tr><td>HGB</td><td>140 g/L</td></tr></table>",
"measured_at": "2024-01-15T10:30:00+02:00"
}'
# 4b. Результат в формате values
curl -s -X POST "https://{clinic_host}/rest/api/provider-lab-requests/result-values" \
-H "X-SERVICE-NAME: {service_name}" \
-H "X-SERVICE-REST-API-KEY: {rest_api_key}" \
-H "Content-Type: application/json" \
-d '{
"request_id": {request_id},
"analyze_id": {analyze_id},
"values": [
{"name": "HGB", "value": "140", "unit": "g/L"},
{"name": "WBC", "value": "8.5", "unit": "10^9/L"}
],
"measured_at": "2024-01-15T10:30:00+02:00"
}'
# 4c. Результат в формате values с нормами и названием (v2.1)
curl -s -X POST "https://{clinic_host}/rest/api/provider-lab-requests/result-values" \
-H "X-SERVICE-NAME: {service_name}" \
-H "X-SERVICE-REST-API-KEY: {rest_api_key}" \
-H "Content-Type: application/json" \
-d '{
"request_id": {request_id},
"analyze_id": {analyze_id},
"values": [
{"name": "HGB", "title": "Гемоглобин", "value": "140", "unit": "g/L",
"reference_range": {"min": 120, "max": 180}},
{"name": "K", "title": "Калий", "value": "8.2", "unit": "ммоль/л",
"reference_range": {"min": 3.5, "max": 5.8}, "flag": "critical_high"}
],
"measured_at": "2024-01-15T10:30:00+02:00"
}'
По вопросам подключения, выдачи ключей и работы Provider API обращайтесь в поддержку Vetmanager по официальным каналам, указанным в вашем договоре/онбординге.
Документ относится к Provider API v2.1. v2.1 полностью совместим с v1: интеграция, которая не использует title/reference_range/flag, продолжает работать без
изменений. Внутренние детали деплоя и инфраструктуры намеренно опущены.