Методи API
Документація Partner API
Цей довідник описує, як ваша інтеграція спілкується з Animal-ID від імені організації: автентифікація, обов'язкові заголовки та основні ендпоінти MVP (власники, тварини, процедури, фото, словники).
SDK та клієнтські бібліотеки
Офіційні open-source SDK, що інкапсулюють підписування запитів і ендпоінти нижче — підключіть їх замість того, щоб підписувати запити вручну.
PHP · Composer
Серверний PHP SDK: HMAC-підписування запитів і типізовані клієнти для кожного ендпоінта.
composer require animal-id/aid-partner-sdk
JavaScript · npm
Пакети для фреймворків (Node і браузер), побудовані на спільному ядрі.
npm i @animal-id/partner-core
- @animal-id/partner-coreНезалежне від фреймворку ядро: підписування + типізований клієнт.
- @animal-id/partner-reactХуки та хелпери React.
- @animal-id/partner-vueКомпозабли Vue.
- @animal-id/partner-angularСервіси Angular.
- @animal-id/partner-nestjsМодуль NestJS для серверних інтеграцій.
Автентифікація та підпис запиту
Базова URL-адреса: https://gw-dev.animal-id.net · усі шляхи мають префікс /v1/partner.
Кожен підписаний запит містить чотири заголовки. Підпис — це HMAC-SHA256 (hex) канонічного рядка, ключем якого є ваш приватний ключ:
stringToSign = METHOD + "\n" + path[?query] + "\n" + sha256_hex(rawBody) + "\n" + timestamp signature = hex( hmac_sha256(stringToSign, privateKey) )
| Заголовок | Значення |
|---|---|
X-Eternity-App-Id | Ідентифікатор вашого застосунку. |
X-Eternity-Public-Key | Ваш публічний ключ. |
X-Eternity-Timestamp | Unix-секунди; має бути в межах ±300s від часу сервера. |
X-Eternity-Signature | Обчислений вище HMAC-SHA256 у hex. |
X-Eternity-Idempotency-Key | UUID, обов'язковий для кожного POST/PATCH/DELETE. Повторні запити повертають першу відповідь; той самий ключ + інше тіло → 409. |
X-Eternity-Animal-ID-Version | Необов'язкова версія дати (YYYY-MM-DD). За замовчуванням — версія, зафіксована під час видачі вашого застосунку; починаючи з 2026-07-04, реєстрація тварини прикріплює наявних власників за public_id замість user_gid. |
X-Eternity-Expand | Необов'язково. JSON-масив ключів розширення для вбудовування додаткових даних на підтримуваних кінцевих точках (напр. ["owners"]). Дивіться розділ «Розширення» кінцевої точки щодо її дозволених ключів; невідомі ключі → 422. |
X-Eternity-Lang-Code | Необов’язковий. Код мови (uk, en, ru, de, es) для назв, які повертає API — наприклад species_name і breed_name на картці тварини та назви в довідниках. Якщо не передано, береться мова за замовчуванням для регіону. |
Підписуйте та надсилайте точно ті самі байти тіла. Для GET/DELETE тіло порожнє (його sha256 — це хеш порожнього рядка). path включає рядок запиту, якщо він присутній. Для завантажень multipart/form-data (фотографії) сире тіло також не є частиною підпису — підписуйте за допомогою sha256 порожнього тіла.
Кожна успішна відповідь обгортає результати в масив payload. Кінцеві точки створення/отримання одного ресурсу повертають масив з одного елемента (напр. { "payload": [ { … } ] }); приклади для кожної кінцевої точки нижче для стислості показують один об'єкт.
APP_ID="aid_app_xxx"; PUBLIC_KEY="pk_xxx"; PRIVATE_KEY="sk_xxx"
METHOD="POST"
PATH_Q="/v1/partner/owners" # path (+ "?query" if any), exactly as sent
BODY='{"email":"jane@example.com","consent":{"account_creation":true}}'
TS=$(date +%s)
BODY_HASH=$(printf '%s' "$BODY" | openssl dgst -sha256 | awk '{print $2}')
STRING_TO_SIGN=$(printf '%s\n%s\n%s\n%s' "$METHOD" "$PATH_Q" "$BODY_HASH" "$TS")
SIG=$(printf '%s' "$STRING_TO_SIGN" | openssl dgst -sha256 -hmac "$PRIVATE_KEY" | awk '{print $2}')
curl -X "$METHOD" "https://gw.animal-id.net$PATH_Q" \
-H "X-Eternity-App-Id: $APP_ID" \
-H "X-Eternity-Public-Key: $PUBLIC_KEY" \
-H "X-Eternity-Timestamp: $TS" \
-H "X-Eternity-Signature: $SIG" \
-H "X-Eternity-Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d "$BODY"const crypto = require('crypto');
function sign({ method, pathQ, body = '', privateKey }) {
const ts = Math.floor(Date.now() / 1000).toString();
const bodyHash = crypto.createHash('sha256').update(body).digest('hex');
const stringToSign = [method, pathQ, bodyHash, ts].join('\n');
const signature = crypto.createHmac('sha256', privateKey).update(stringToSign).digest('hex');
return { ts, signature };
}
const body = JSON.stringify({ email: 'jane@example.com' });
const { ts, signature } = sign({ method: 'POST', pathQ: '/v1/partner/owners', body, privateKey: 'sk_xxx' });
await fetch('https://gw.animal-id.net/v1/partner/owners', {
method: 'POST',
headers: {
'X-Eternity-App-Id': 'aid_app_xxx',
'X-Eternity-Public-Key': 'pk_xxx',
'X-Eternity-Timestamp': ts,
'X-Eternity-Signature': signature,
'X-Eternity-Idempotency-Key': crypto.randomUUID(),
'Content-Type': 'application/json',
},
body, // sign and send the SAME bytes
});import hashlib, hmac, time, json, uuid, requests
def sign(method, path_q, body, private_key):
ts = str(int(time.time()))
body_hash = hashlib.sha256(body.encode()).hexdigest()
string_to_sign = "\n".join([method, path_q, body_hash, ts])
signature = hmac.new(private_key.encode(), string_to_sign.encode(), hashlib.sha256).hexdigest()
return ts, signature
body = json.dumps({"email": "jane@example.com"}, separators=(",", ":"))
ts, signature = sign("POST", "/v1/partner/owners", body, "sk_xxx")
requests.post(
"https://gw.animal-id.net/v1/partner/owners",
data=body, # send the SAME bytes you signed
headers={
"X-Eternity-App-Id": "aid_app_xxx",
"X-Eternity-Public-Key": "pk_xxx",
"X-Eternity-Timestamp": ts,
"X-Eternity-Signature": signature,
"X-Eternity-Idempotency-Key": str(uuid.uuid4()),
"Content-Type": "application/json",
},
)<?php
function signRequest(string $method, string $pathQ, string $body, string $privateKey): array {
$ts = (string) time();
$bodyHash = hash('sha256', $body);
$stringToSign = implode("\n", [$method, $pathQ, $bodyHash, $ts]);
$signature = hash_hmac('sha256', $stringToSign, $privateKey);
return [$ts, $signature];
}
$body = json_encode(['email' => 'jane@example.com']);
[$ts, $signature] = signRequest('POST', '/v1/partner/owners', $body, 'sk_xxx');
$ch = curl_init('https://gw.animal-id.net/v1/partner/owners');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body, // send the SAME bytes you signed
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"X-Eternity-App-Id: aid_app_xxx",
"X-Eternity-Public-Key: pk_xxx",
"X-Eternity-Timestamp: $ts",
"X-Eternity-Signature: $signature",
'X-Eternity-Idempotency-Key: ' . bin2hex(random_bytes(16)),
'Content-Type: application/json',
],
]);
$response = curl_exec($ch);Вебхуки
Отримуйте відкладені події — наприклад, коли власник погоджує запит ветеринара на доступ — як підписані POST-запити на ваш сервер. Вкажіть URL і знайдіть секрет підпису на вкладці API-ключів.
Підписана доставка вебхукаПідпис та тіло вебхука▸Ми надсилаємо POST для кожної події на вказаний вами URL вебхука, підписаний вашим окремим секретом вебхука (показується один раз під час генерації). Перевірте підпис, перш ніж довіряти доставці: перерахуйте HMAC за канонічним рядком і порівняйте за сталий час:
canonical = "POST" + "\n" + path[?query] + "\n" + sha256_hex(rawBody) + "\n" + timestamp signature = hex( hmac_sha256(canonical, webhookSecret) )
| Заголовок | Значення |
|---|---|
X-Eternity-Webhook-Id | Унікальний ідентифікатор доставки (UUID); незмінний при повторних надсиланнях тієї самої події. |
X-Eternity-Webhook-Event | Ключ події, напр. animal_access.approved. |
X-Eternity-Webhook-Timestamp | Unix-секунди, коли доставку було підписано; відхиляйте доставки з розбіжним часом. |
X-Eternity-Webhook-Signature | HMAC-SHA256 (hex) канонічного рядка, ключем є ваш секрет вебхука (не приватний ключ API). |
Тіло доставки (JSON)
{
"id": "5f1c0b8e-3a2d-4c7b-9b1a-2e6f0d4c8a91",
"event": "animal_access.approved",
"occurred_at": "2026-06-24T09:15:00+00:00",
"result": {
"animal_id": "8xK3pQzVnB7rL2qF",
"requester_user_gid": 90231,
"status": "granted",
"requested_at": "2026-06-23T09:00:00+00:00",
"expires_at": "2026-06-30T09:00:00+00:00",
"retry_after_seconds": 0,
"decided_at": "2026-06-24T09:15:00+00:00"
}
}| Поле | Опис |
|---|---|
id | Унікальний ідентифікатор події (збігається із заголовком X-Eternity-Webhook-Id). |
event | Ключ події, напр. animal_access.approved. |
occurred_at | Коли сталася подія (ISO 8601). |
result | Рішення щодо доступу. Повторює GET /v1/partner/animals/{id}/access-request і додає animal_id, requester_user_gid та decided_at. |
Події
| Ключ | Значення |
|---|---|
animal_access.approved | Власник погодив ваш запит на доступ, що очікував — тепер ви можете редагувати тварину. |
animal_access.denied | Власник відхилив ваш запит на доступ — ви можете повторити запит після завершення терміну дії. |
consent.approved | Людина, яку ви питали, дозволила — можете користуватися дозволом, доки він не закінчиться. |
consent.denied | Людина, яку ви питали, відхилила запит. Нічого не надано. |
consent.revoked | Наданий вам дозвіл відкликано. Якщо це був переданий ключ, він одразу перестає працювати. |
consent.expired | Ніхто не відповів вчасно, і запит утратив силу. Це не відмова — можете спитати ще раз. |
Тіло події про згоду
Події про згоду доставляються вашому застосунку-платформі, а не організації: коли лікар дозволяє вам тримати ключ, що діє від його імені, жодна клініка в цьому не бере участі.
{
"id": "282824f1-b65e-40f4-86d1-62a2bac566df",
"event": "consent.revoked",
"occurred_at": "2026-08-26T19:45:00+00:00",
"result": {
"consent_id": "qeHSuvlSZHAWpacF",
"kind": "key_handover",
"status": "revoked",
"doctor_id": "c71ORqKq81fRoTcm",
"clinic_id": null,
"decided_at": "2026-08-26T19:45:00+00:00"
}
}| Поле | Опис |
|---|---|
consent_id | Запит, до якого належить це рішення, — той самий ідентифікатор, що повернув виклик провіженінгу. |
kind | key_handover (ключ, що діє від імені лікаря) або clinic_membership (додавання лікаря до клініки). |
status | approved, denied, revoked або expired. |
doctor_id | Публічний ідентифікатор лікаря — для передавання ключа. Інакше null; також null, якщо акаунт відтоді видалено. |
clinic_id | Публічний ідентифікатор клініки — для членства в клініці. Інакше null. |
decided_at | Коли настав цей стан (ISO 8601). Для спливання це кінцевий термін, а не момент, коли ми це помітили. |
Обробляйте consent.revoked. Дозвіл можна відкликати будь-коли, і переданий ключ перестає працювати тієї ж миті — без цієї події ви дізнаєтесь про це лише тоді, коли впаде наступний виклик.
Підтверджуйте будь-якою відповіддю 2xx. Статус, відмінний від 2xx, або таймаут записується як невдала доставка, яку ви можете надіслати повторно з журналу доставок вебхуків у кабінеті.
const crypto = require('crypto');
// Express: mount with a raw-body parser so you verify the EXACT bytes received.
// app.post('/animal-id/webhook', express.raw({ type: 'application/json' }), handler)
function verify(req, webhookSecret) {
const ts = req.header('X-Eternity-Webhook-Timestamp');
const sig = req.header('X-Eternity-Webhook-Signature');
const path = req.originalUrl; // path (+ ?query) exactly as received
const raw = req.body; // Buffer of the raw request body
const bodyHash = crypto.createHash('sha256').update(raw).digest('hex');
const canonical = ['POST', path, bodyHash, ts].join('\n');
const expected = crypto.createHmac('sha256', webhookSecret).update(canonical).digest('hex');
return sig && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}<?php
// Verify a webhook delivery from Animal ID before trusting it.
function verifyWebhook(string $rawBody, string $path, string $webhookSecret): bool {
$ts = $_SERVER['HTTP_X_ETERNITY_WEBHOOK_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_ETERNITY_WEBHOOK_SIGNATURE'] ?? '';
$canonical = implode("\n", ['POST', $path, hash('sha256', $rawBody), $ts]);
$expected = hash_hmac('sha256', $canonical, $webhookSecret);
return $sig !== '' && hash_equals($expected, $sig);
}
$rawBody = file_get_contents('php://input'); // verify the EXACT bytes received
if (!verifyWebhook($rawBody, $_SERVER['REQUEST_URI'], getenv('AID_WEBHOOK_SECRET'))) {
http_response_code(401);
exit;
}
$event = json_decode($rawBody, true); // ['id' => …, 'event' => …, 'result' => …]
http_response_code(204); // acknowledge with any 2xxМетоди API
Почніть вводити — розділи відфільтруються за ключовими словами.
Platform API — заведення
Створення клінік і лікарів та запити дозволу в людей, який неможливо взяти самому. Саме звідси починається інтеграція: спершу заводите акаунти, потім отримуєте ключі, якими з ними працюватимете.
- Підписується ключем платформи, який видається вам один раз при заведенні партнерського акаунта. У X-Eternity-App-Id надсилайте uuid застосунку платформи.
- До даних тварин він не дістає ніколи. Ключ платформи на шляху /v1/partner/ віддасть 401 — це працює розділення, а не помилка налаштування.
/v1/platform/organizationsЗнайти вже наявну клініку, перш ніж створювати нову.▸Автентифікація: HMAC with your PLATFORM key.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
query | так | string | — | Фрагмент назви або адреси, щонайменше 2 символи. |
limit | ні | int | — | Максимум результатів, до 50 (типово 20). |
Приклад відповіді
{
"payload": [
{
"public_id": "TGo1Gwe2ppRkUFO1",
"org_name": "Лапа",
"full_address": "Україна, Київ, вул. Прикладна, 1",
"status": 3,
"linked": false
}
]
}| Поле | Опис |
|---|---|
public_id | Передайте його в ендпоінт нижче, щоб завести сюди лікаря. |
status | Статус модерації. Заведена вами клініка лишається поза публічним каталогом, доки її не забере директор. |
linked | true, якщо цю клініку завели саме ви. |
Статуси відповіді
| Статус | Значення |
|---|---|
200 | Збіги (порожній список, якщо нічого не знайдено). |
422 | Помилка валідації (query відсутній або коротший за 2 символи). |
/v1/platform/organizationsСтворити клініку або знайти вже створену за вашим ідентифікатором.▸Автентифікація: HMAC with your PLATFORM key. Issued separately from clinic keys; it never reaches animal data.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
external_org_id | так | string | — | Ваш власний ідентифікатор цієї клініки. Повторний виклик із тим самим значенням поверне вже створену клініку, а не зробить другу — тож передавайте стабільне значення. |
name | так | string | — | Clinic name. |
director_public_id | так | string | — | Лікар, який займе місце директора, — за його public_id (з POST /owners або з ендпоінта нижче). Клініка не може існувати без директора, і один лікар може директорувати лише в одній клініці; якщо названа людина вже директорує деінде, відповідь буде 409. |
email | ні | string | — | Contact email. |
phone | ні | string | — | Contact phone (E.164). |
website | ні | string | — | Website. |
address | ні | string | — | Full address. |
country_id | ні | int | countries | Country dictionary id. |
description | ні | string | — | Free-text description. |
lat | ні | number | — | Latitude. |
lng | ні | number | — | Longitude. |
Тіло запиту (JSON)
{
"external_org_id": "crm-clinic-118",
"name": "Лапа",
"director_public_id": "V1StGXR8Z5jd",
"email": "clinic@example.com",
"phone": "+380441234567"
}Приклад відповіді
{
"payload": {
"public_id": "yAvgJrSYehJo9JXh",
"name": "Лапа",
"status": 2,
"created": true
}
}| Поле | Опис |
|---|---|
public_id | Стабільний публічний ідентифікатор клініки — передайте його в ендпоінт нижче. |
created | true, якщо клініку створив саме цей виклик; false, якщо повернуто вже наявну. |
status | Статус модерації. Заведена клініка лишається поза публічним каталогом, доки її не забере директор. |
Статуси відповіді
| Статус | Значення |
|---|---|
201 | Clinic created. |
200 | Клініка для цього external_org_id уже існувала — повернено ту саму. |
409 | Вказаний директор уже керує іншою клінікою. Вкажіть іншого лікаря. |
422 | Помилка валідації (відсутні external_org_id, name або director_public_id). |
/v1/platform/organizations/{clinic_public_id}/membersЗавести лікаря в клініку й отримати його ключі.▸Автентифікація: HMAC with your PLATFORM key.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
email | умовно | string | — | Email лікаря. Потрібен або email, або телефон. |
phone | умовно | string | — | Телефон лікаря (E.164). Потрібен або email, або телефон. |
first_name | ні | string | — | Ім'я. |
last_name | ні | string | — | Прізвище. |
language | ні | string | languages | Бажана локаль. |
clinic_name | ні | string | — | Підпис, який показується на виданих креденшелах. |
external_doctor_id | ні | string | — | Ваш власний ідентифікатор цього лікаря. Те саме поле й ті самі правила, що й external_owner_id: пишеться один раз, не перезаписується і видимий лише вам. |
consent | так | object | — | Блок згоди (незмінний аудит). |
consent.account_creation | так | bool | — | Має бути true. Ключі, які ви отримуєте, діють від імені цієї людини, тож її згода обов’язкова. |
Тіло запиту (JSON)
{
"email": "doctor@example.com",
"first_name": "Ihor",
"last_name": "Melnyk",
"language": "uk",
"external_doctor_id": "crm-doc-4471",
"consent": { "account_creation": true }
}Приклад відповіді
{
"payload": {
"public_id": "LSG9w6B2rwAiPoJD",
"app_id": "4833d2e5-1a97-4572-ac5d-a03c7614e0d7",
"public_key": "94af0494...",
"private_key": "b208c6e0...",
"created": true
}
}| Поле | Опис |
|---|---|
app_id | App-Id, яким цей лікар підписує виклики площини даних (X-Eternity-App-Id). |
public_key | Публічна половина пари ключів лікаря. |
private_key | Приватна половина. Показується в цій відповіді й більше ніколи — збережіть її до закриття з’єднання. |
public_id | Стабільний публічний ідентифікатор лікаря — використовуйте його всюди, де називається власник або директор. |
created | true, якщо акаунт створив саме цей виклик; false, якщо лікар уже мав акаунт і його знайдено. |
Статуси відповіді
| Статус | Значення |
|---|---|
201 | Лікаря заведено; креденшели повернуто. |
409 | Цей лікар уже має ключ для цієї клініки, або клініку створювали не ви і її директор вас не схвалив — спершу підніміть запит clinic_membership. |
422 | Помилка валідації (немає email/телефона або не прийнято consent.account_creation). |
/v1/platform/organizations/{clinic_public_id}/members/{doctor_public_id}/credentialsОтримати ключі, що діють від імені лікаря, який на це погодився.▸Автентифікація: HMAC with your PLATFORM key.
Приклад відповіді
{
"payload": {
"public_id": "LSG9w6B2rwAiPoJD",
"app_id": "dcd4895e-550e-424a-9c5d-5206cbce2956",
"public_key": "11fff5d1...",
"private_key": "00604b9b...",
"created": false
}
}| Поле | Опис |
|---|---|
private_key | Показується один раз і більше ніколи. Ключ належить вам і відокремлений від власного ключа лікаря — коли він відкличе згоду, ваш перестане працювати, а його ні. |
Статуси відповіді
| Статус | Значення |
|---|---|
201 | Ключі видано. |
409 | Лікар не погодився на передачу, або з цією клінікою ви працювати не можете. У повідомленні сказано, що саме. |
/v1/platform/consentsПопросити дозволу в лікаря або клініки.▸Автентифікація: HMAC with your PLATFORM key.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
kind | так | string | — | key_handover — тримати ключі, що діють від імені цього лікаря; дозволити це може лише сам лікар. clinic_membership — завести лікаря в клініку, якої ви не створювали; вирішує її директор. |
doctor_public_id | так | string | — | Лікар, якого стосується запит. |
clinic_public_id | умовно | string | — | Обовʼязково для clinic_membership: клініка, директора якої ви питаєте. |
Тіло запиту (JSON)
{
"kind": "clinic_membership",
"doctor_public_id": "LSG9w6B2rwAiPoJD",
"clinic_public_id": "jJlmHf0sgxMT3Gni"
}Приклад відповіді
{
"payload": {
"public_id": "5G5rBYl0hQvpJuCZ",
"kind": "clinic_membership",
"status": "pending",
"expires_at": 1788973565,
"decided_at": null
}
}| Поле | Опис |
|---|---|
public_id | За ним опитуйте статус. |
status | pending, доки людина не відповість, далі approved або denied. |
expires_at | Unix-секунди. Запит без відповіді закривається сам, і схвалення перестає діяти в той самий момент — дозвіл не безстроковий. |
Статуси відповіді
| Статус | Значення |
|---|---|
201 | Запит створено, або повернуто вже наявний — повторне звернення не створює другий. |
409 | Немає кому це вирішувати (наприклад, клініка без директора). |
422 | Помилка валідації (невідомий kind або відсутній clinic_public_id для clinic_membership). |
/v1/platform/consents/{public_id}Перевірити, на якому етапі запит дозволу.▸Автентифікація: HMAC with your PLATFORM key.
Приклад відповіді
{
"payload": {
"public_id": "5G5rBYl0hQvpJuCZ",
"kind": "clinic_membership",
"status": "approved",
"expires_at": 1788973565,
"decided_at": 1787763211
}
}Статуси відповіді
| Статус | Значення |
|---|---|
200 | Поточний стан. |
404 | Такого запиту немає або він належить іншому партнеру. |
Partner API — дані
Тварини, власники, процедури та фото — щоденна поверхня. Кожен запис тут фіксується від імені лікаря, чиїм ключем його підписано.
- Підписується ключем лікаря, який повертається один раз — коли ви заводите лікаря в клініку або отримуєте його креденшели після згоди. У X-Eternity-App-Id надсилайте uuid застосунку цього лікаря.
- Заводити нічого не може і перестає працювати тієї миті, коли лікар відкликає дозвіл. Довідники не потребують підпису взагалі.
/v1/partner/dictionariesДовідники (багатомовні, з фільтрацією).▸Автентифікація: Публічна (підпис не потрібен). Кешується на CDN через ETag.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
include | ні | string (csv) | — | Ключі довідників через кому; порожнє значення — усі. Ключі: species, pet_species_featured, sex, sizes, lost_statuses, other_identifiers, procedure_types, countries, languages, cites. `pet_species_featured` — канонічний список популярних видів із public_id у форматі UUID; передавайте його код у POST /animals як species_public_id. |
q | ні | string | — | Фільтрувати записи за локалізованою назвою будь-якою активною мовою. |
lang | ні | string | languages | Проєктувати назви на одну локаль (uk, en, ru, de, es). За замовчуванням: усі активні. |
Приклад відповіді
{
"payload": [
{
"key": "species",
"items": [
{ "code": 3, "names": { "uk": "Собаки", "en": "Dogs", "ru": "Собаки", "de": "Dogs" } },
{ "code": 4, "names": { "uk": "Коти", "en": "Cats" } }
]
},
{
"key": "pet_species_featured",
"items": [
{ "code": "1b289672-0a74-48d2-9600-7104bedacd8c", "names": { "uk": "Собака", "en": "Dog" } },
{ "code": "b0dd3c3a-4d35-4479-91f9-616ae072c400", "names": { "uk": "Домашні коти", "en": "Domestic cats" } }
]
},
{
"key": "countries",
"items": [
{ "code": "804", "alpha2": "UA", "alpha3": "UKR",
"names": { "uk": "Україна", "en": "Ukraine", "ru": "Украина", "de": "Ukraine", "es": "Ukraine" } }
]
},
{
"key": "languages",
"items": [
{ "code": "uk", "native": "Українська",
"names": { "uk": "Українська", "en": "Ukrainian", "ru": "Украинский", "de": "Ukrainian", "es": "Ukrainian" } }
]
}
],
"metadata": { "etag": "W/\"dict-…\"", "generated_at": "2026-05-30T08:00:00+00:00", "languages": ["uk","en","ru","de","es"] },
"links": [],
"message": null
}| Поле | Опис |
|---|---|
payload[].key | Ключ словника. |
payload[].items[].code | Стабільний id, який використовується як значення в ендпоінтах запису. Числовий для більшості довідників (species, sex, …); для pet_species_featured це канонічний public_id виду (UUID) → передавайте його як species_public_id у POST /animals; для countries це доповнений нулями числовий код ISO 3166-1 у вигляді рядка (напр. "004", "804"); для languages це код ISO 639-1 (напр. "uk"). |
payload[].items[].names | Зіставляє локаль → локалізована назва. Локалі без перекладу повертаються до англійської. |
payload[].items[].alpha2 / alpha3 | Лише для countries: коди ISO 3166-1 alpha-2 / alpha-3 для зручного зіставлення. |
payload[].items[].native | Лише для languages: власна назва мови (ендонім), зручно для вибору мови. |
metadata.etag | Передайте назад у If-None-Match, щоб отримати 304, якщо змін немає. |
metadata.languages | Активні локалі, фактично присутні в цій збірці. |
Статуси відповіді
| Статус | Значення |
|---|---|
200 | OK — словники повернено. |
304 | Not Modified — ваш If-None-Match збігається; використовуйте кешовану копію. |
/v1/partner/dictionaries/speciesПошук видів тварин (канонічний, за public_id).▸Автентифікація: Public (no signature required).
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
q | ні | string | — | Пошуковий запит за видом (будь-який таксономічний ранг, підрядок і терпимість до одруківок). Не передавайте, щоб переглянути найкращі збіги. Доповнює довідник pet_species_featured, у якому лише популярні види. |
Приклад відповіді
{
"payload": [
{ "public_id": "1b289672-0a74-48d2-9600-7104bedacd8c", "name": "Dog", "rank": "species", "has_breeds": true },
{ "public_id": "9cd7d2a1-4e45-4922-8f9e-fb84c61ca6ae", "name": "Cats", "rank": "genus", "has_breeds": false }
]
}| Поле | Опис |
|---|---|
payload[].public_id | public_id виду — передайте його як species_public_id у POST /animals або в /dictionaries/species/{species_public_id}/breeds. |
payload[].name | Локалізована назва виду (мова запиту, фолбек — англійська). |
payload[].rank | Таксономічний ранг (вид, рід, родина, …). |
payload[].has_breeds | Чи має цей вид список порід. |
Статуси відповіді
| Статус | Значення |
|---|---|
200 | OK — matching species. |
/v1/partner/dictionaries/species/{species_public_id}/breedsПороди для виду (канонічні, за public_id).▸Автентифікація: Public (no signature required).
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
species_public_id | так | string | — | Сегмент шляху: public_id виду (UUID). Знайти його можна через pet_species_featured або /dictionaries/species. |
q | ні | string | — | Необовʼязковий фільтр за назвою породи (підрядок, терпимий до одруківок). |
Приклад відповіді
{
"payload": [
{ "public_id": "6bb37956-d7fb-426d-8045-9d2fb854ee43", "name": "Belgian Shepherd Dog", "kind": "purebred" },
{ "public_id": "d1f2a0c8-7b3e-4a1d-9c22-0f5e6b7a8c90", "name": "Mixed breed", "kind": "mixed" }
]
}| Поле | Опис |
|---|---|
payload[].public_id | Канонічний public_id породи — передайте його як breed_public_id у POST /animals. |
payload[].name | Локалізована назва породи (мова запиту, фолбек — англійська). |
payload[].kind | purebred | mixed | unknown | crossbreed | variety. mixed/unknown/crossbreed — спеціальні службові варіанти. |
Статуси відповіді
| Статус | Значення |
|---|---|
200 | OK — породи цього виду (порожній список, якщо порід немає). |
404 | species_public_id не є коректним UUID (маршрут не збігся). |
/v1/partner/ownersСтворити (або знайти) власника; повертає глобальний ID користувача.▸Автентифікація: HMAC. Будь-який ключ партнера. · X-Eternity-Idempotency-Key обов'язково
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
email | умовно | string | — | Email власника. Потрібен один з email/phone — це спосіб подальшого зв'язку з власником / його автентифікації. |
phone | умовно | string | — | Телефон власника (E.164). Потрібен один з email/phone. |
first_name | ні | string | — | Ім'я. |
last_name | ні | string | — | Прізвище. |
language | ні | string | languages | Бажана локаль. |
country | ні | string | countries | Доповнений нулями числовий код ISO 3166-1 у вигляді рядка (напр. "804") — відповідає коду словника countries. |
external_owner_id | ні | string | — | Ваш власний ідентифікатор цієї людини. Зберігається один раз, при першому контакті, і ніколи не перезаписується — передавайте його, щоб обидві сторони могли звірити ту саму людину пізніше. Максимум 128 символів. |
consent | так | object | — | Блок згоди (незмінний аудит). |
consent.account_creation | так | bool | — | Має бути true — власник погодився на створення облікового запису. Час фіксації записується на стороні сервера. |
Тіло запиту (JSON)
{
"email": "jane@example.com",
"phone": "+380681234567",
"first_name": "Jane",
"last_name": "Doe",
"language": "uk",
"country": "804",
"external_owner_id": "crm-4471",
"consent": {
"account_creation": true
}
}Приклад відповіді
{
"payload": {
"user_gid": 90231,
"public_id": "V1StGXR8Z5jd",
"has_account": true,
"email": "jane@example.com",
"phone": null,
"display_hint": "Ол*** К.",
"language": "uk",
"country_id": 804,
"external_owner_id": "crm-4471"
}
}| Поле | Опис |
|---|---|
public_id | Стабільний публічний ідентифікатор власника — передайте його в POST /animals owners[].public_id (версія API >= 2026-07-04). |
user_gid | Застарілий числовий ідентифікатор власника (прикріплення власника у старих версіях API). |
has_account | Чи має власник уже придатний для використання обліковий запис. |
email | Email, що зберігається для цього власника (null, якщо невідомий). |
phone | Телефон, що зберігається для цього власника (null, якщо невідомий). |
display_hint | Замасковане відображуване ім'я (без персональних даних). |
external_owner_id | Ідентифікатор, який ВИ передали нам для цієї людини, або null, якщо не передавали. Обмежений вашою інтеграцією — ви ніколи не бачите, як ту саму людину називає інший партнер. |
Статуси відповіді
| Статус | Значення |
|---|---|
201 | Created (або знайдено наявного власника — ідемпотентно за email/phone). |
409 | X-Eternity-Idempotency-Key повторно використано з іншим тілом або ще обробляється. |
422 | Помилка валідації (відсутній email/phone або consent.account_creation не прийнято). |
/v1/partner/owners/searchЗнайти власника за точним email або телефоном.▸Автентифікація: HMAC. Будь-який ключ партнера.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
email_or_phone | так | string | — | Точний email або телефон (одне поле; email визначається за форматом). |
Приклад відповіді
{
"payload": { "user_gid": 90231, "public_id": "V1StGXR8Z5jd", "has_account": true, "email": "jane@example.com", "phone": null, "display_hint": "Ол*** К.", "language": "uk", "country_id": 804, "external_owner_id": "crm-4471" }
}| Поле | Опис |
|---|---|
public_id | Стабільний публічний ідентифікатор власника — передайте його в POST /animals owners[].public_id (версія API >= 2026-07-04). |
user_gid | Застарілий числовий ідентифікатор власника (прикріплення власника у старих версіях API). |
email | Email, що зберігається для цього власника (null, якщо невідомий). |
phone | Телефон, що зберігається для цього власника (null, якщо невідомий). |
external_owner_id | Ідентифікатор, який ВИ передали нам для цієї людини, або null, якщо не передавали. Обмежений вашою інтеграцією — ви ніколи не бачите, як ту саму людину називає інший партнер. |
Статуси відповіді
| Статус | Значення |
|---|---|
200 | Власника знайдено. |
404 | Немає власника з таким email_or_phone. |
422 | email_or_phone є обов'язковим. |
/v1/partner/animalsЗареєструвати тварину (за чипом).▸Автентифікація: HMAC. Ключ ветеринара/організації. · X-Eternity-Idempotency-Key обов'язково
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
species | умовно | int | species | Застарілий id виду з довідника. Потрібен рівно один із species / species_public_id. |
species_public_id | умовно | string | pet_species_featured | Канонічний public_id виду (UUID) із довідника pet_species_featured. Потрібен рівно один із species / species_public_id; якщо переданий — має перевагу над species. |
is_microchip | так | bool | — | Чи має тварина чип. true → microchip є обов'язковим; false → microchip ігнорується, і реєстр призначає тимчасовий номер WC. |
microchip | умовно | string | — | Мікрочип (транспондер). Обов'язковий лише коли is_microchip = true. |
nickname | так | string | — | Кличка тварини. |
qr_tag | ні | string | — | Серійний номер QR-паспорта для прикріплення під час реєстрації. |
owners | ні | array | — | Власники; перший стає main_owner, решта — owners (дедуплікуються). Кожен запис або прикріплює наявного власника, АБО реєструє нового вбудовано. |
owners[].public_id | умовно | string | — | Режим прикріплення (версія API >= 2026-07-04): public_id наявного власника з POST/GET owners. Пропустіть, щоб зареєструвати вбудовано. |
owners[].user_gid | умовно | int | — | Режим прикріплення (версії API до 2026-07-04): застарілий числовий ідентифікатор власника. Пропустіть, щоб зареєструвати вбудовано. |
owners[].email | умовно | string | — | Вбудований режим: email власника. Потрібен один з email/phone, коли немає public_id/user_gid (upsert — без дублікатів). |
owners[].phone | умовно | string | — | Вбудований режим: телефон власника (E.164). |
owners[].first_name | ні | string | — | Вбудований режим: ім'я. |
owners[].last_name | ні | string | — | Вбудований режим: прізвище. |
owners[].language | ні | string | languages | Вбудований режим: бажана локаль. |
owners[].country | ні | string | countries | Вбудований режим: доповнений нулями числовий код ISO 3166-1 у вигляді рядка (напр. "804") — відповідає коду словника countries. |
owners[].external_owner_id | ні | string | — | Inline-режим: ваш власний ідентифікатор цієї людини — те саме поле й ті самі правила, що й у POST /owners. |
owners[].consent.account_creation | умовно | bool | — | Вбудований режим: має бути true — власник погодився на створення облікового запису. Обов'язково лише при вбудованій реєстрації. |
breed | ні | string | — | Порода (вільний текст). Використовується, лише якщо breed_public_id відсутній. |
breed_public_id | ні | string | — | Канонічний public_id породи (UUID) із GET /breeds?species_public_id=. Має належати цьому виду; якщо переданий — має перевагу над текстовою породою. |
color | ні | string | — | Колір (вільний текст — без словника). |
gender_id | ні | int | sex | Ідентифікатор словника gender. |
dob | ні | date | — | Дата народження (ISO 8601). |
microchip_date | ні | date | — | Коли було імплантовано чип (ISO 8601). |
sterilization | ні | bool | — | Прапорець стерилізації. |
size | ні | int | sizes | Ідентифікатор словника size. |
identifiers | ні | array | — | Додаткові ідентифікатори, окрім microchip/qr. |
identifiers[].type | так | int | other_identifiers | Ідентифікатор типу зі словника other_identifiers (tattoo, ring, …). |
identifiers[].value | так | string | — | Значення ідентифікатора. |
identifiers[].added_at | ні | date | — | Коли було призначено ідентифікатор (ISO 8601). |
Тіло запиту (JSON)
{
"species": 3,
"is_microchip": true,
"microchip": "900263000123456",
"nickname": "Барсік",
"qr_tag": null,
"gender_id": 1,
"breed": "Labrador",
"color": "black",
"dob": "2022-03-01T00:00:00+00:00",
"microchip_date": "2022-11-20T00:00:00+00:00",
"sterilization": true,
"size": 2,
"owners": [
{ "public_id": "V1StGXR8Z5jd" },
{
"email": "jane@example.com",
"phone": "+380681234567",
"first_name": "Jane",
"last_name": "Doe",
"external_owner_id": "crm-4471",
"consent": { "account_creation": true }
}
],
"identifiers": [
{ "type": 3, "value": "TAT-001", "added_at": "2026-05-01T00:00:00+00:00" }
]
}Приклад відповіді
{ "payload": { "id": "8xK3pQzVnB7rL2qF" } }| Поле | Опис |
|---|---|
id | Невгадуваний публічний ідентифікатор тварини (NanoID). Використовуйте його в усіх подальших викликах для тварини. |
Статуси відповіді
| Статус | Значення |
|---|---|
201 | Тварину зареєстровано. |
409 | Конфлікт X-Eternity-Idempotency-Key (той самий ключ, інше тіло). |
422 | Помилка валідації: немає nickname/is_microchip або жодного з species та species_public_id; невідомий species_public_id/breed_public_id чи breed_public_id, який не належить цьому виду; is_microchip=true без коректного мікрочипа; дубль мікрочипа (такий транспондер уже зареєстровано, поле "transponder"); або вбудований власник без email/телефона чи без consent.account_creation. |
/v1/partner/animals/by-identifier/{type}/{value}Пошук за конкретним типом ідентифікатора. Завжди масив.▸Автентифікація: HMAC. Будь-який ключ партнера.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
type | так | path enum | — | microchip або qr_tag. |
value | так | path string | — | Значення ідентифікатора для пошуку. |
Приклад відповіді
{
"payload": [
{ "id": "8xK3pQzVnB7rL2qF", "species": 3,
"species_public_id": "d49c523a-d7ff-41b4-9ab6-0d1d2ce20939", "species_name": "Собака",
"breed": "Labrador", "breed_public_id": null, "breed_name": null,
"color": "black", "gender_id": 1,
"nickname": "Барсік", "microchip": "900263000123456", "qr_tag": null,
"dob": "2022-03-01", "register_date": "2026-05-30", "sterilization_status": true,
"lost_status": null, "deceased": false, "died_at": null, "status": 1,
"abilities": { "can_edit": true } }
]
}| Поле | Опис |
|---|---|
payload | Масив карток тварин — зазвичай одна, але значення може відповідати кільком. |
species_public_id | Канонічний public_id виду — той самий ключ, який ви передаєте назад як species_public_id у POST /animals. |
species_name | Назва виду мовою запиту (фолбек — англійська, далі латинська назва). |
breed_public_id | Канонічний public_id породи або null, якщо у тварини лише текстова порода. |
breed_name | Канонічна назва породи мовою запиту; null, коли breed_public_id порожній — тоді читайте `breed`. |
microchip / qr_tag | Активні ідентифікатори. |
lost_status | "active", коли повідомлено про втрату, інакше null. |
deceased | True, щойно зафіксовано евтаназію/смерть. |
Дозволи
Кожен об'єкт тварини містить об'єкт abilities, що описує, які дії автентифікований користувач-партнер може виконувати з цією твариною. Це перший прапорець доступу; з часом будуть додані нові.
| Поле | Опис |
|---|---|
abilities.can_edit | Чи може автентифікований користувач-партнер редагувати цю тварину — оновлювати її дані, додавати процедури та керувати фотографіями. True, коли користувач зареєстрував тварину, має будь-який зв'язок із нею (animal_user_relation) або є активним членом організації, у реєстрі якої вона є (org_animals). |
Розширення (X-Eternity-Expand)
Необов'язковий заголовок, що містить JSON-масив ключів розширення (напр. ["owners"]). Кожен запитаний ключ вбудовує додаткове поле в кожен об'єкт тварини у відповіді; пропустіть заголовок, щоб отримати звичайну картку. Невідомі ключі відхиляються з 422.
| Ключ | Додає | Опис |
|---|---|---|
owners | owners[] | Власники тварини — головний власник плюс будь-які співвласники — кожен із контактними даними та прапорцем is_main_owner. Доступно лише на цьому інтерфейсі партнера. |
"owners": [
{
"user_gid": 90231,
"public_id": "V1StGXR8Z5jd",
"has_account": true,
"email": "jane@example.com",
"phone": "+380681234567",
"display_hint": "Ja*** D.",
"language": "uk",
"country_id": "804",
"external_owner_id": "crm-4471",
"is_main_owner": true
}
]| Поле | Опис |
|---|---|
owners[].public_id | Стабільний публічний ідентифікатор власника — передайте його в POST /animals owners[].public_id (версія API >= 2026-07-04). |
owners[].user_gid | Застарілий числовий ідентифікатор власника (прикріплення власника у старих версіях API). |
owners[].has_account | Чи має власник уже придатний для використання обліковий запис. |
owners[].email | Email, що зберігається для цього власника (null, якщо невідомий). |
owners[].phone | Телефон, що зберігається для цього власника (null, якщо невідомий). |
owners[].display_hint | Замасковане відображуване ім'я (без персональних даних). |
owners[].language | Бажана локаль. |
owners[].country_id | Доповнений нулями числовий код ISO 3166-1 у вигляді рядка (напр. "804"). |
owners[].external_owner_id | Ідентифікатор, який ВИ передали нам для цієї людини, або null, якщо не передавали. Обмежений вашою інтеграцією — ви ніколи не бачите, як ту саму людину називає інший партнер. |
owners[].is_main_owner | true для головного власника (animal_user_relation типу main_owner); false для співвласників. |
Статуси відповіді
| Статус | Значення |
|---|---|
200 | OK — масив (можливо, порожній). |
/v1/partner/animals/by-identifier/{value}Пошук за всіма типами ідентифікаторів одразу. Завжди масив.▸Автентифікація: HMAC. Будь-який ключ партнера.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
value | так | path string | — | Значення ідентифікатора; шукається серед microchip та qr_tag. |
Приклад відповіді
{ "payload": [ { "id": "8xK3pQzVnB7rL2qF", "nickname": "Барсік", "microchip": "900263000123456",
"species": 3, "species_public_id": "d49c523a-d7ff-41b4-9ab6-0d1d2ce20939",
"species_name": "Собака", "breed": "Labrador",
"breed_public_id": null, "breed_name": null } ] }| Поле | Опис |
|---|---|
species_public_id / breed_public_id | Канонічні ключі — ті самі, що приймає POST /animals. breed_public_id порожній, доки у тварини лише текстова порода. |
species_name / breed_name | Назви мовою запиту (фолбек — англійська, далі латинська/канонічна назва). |
Дозволи
Кожен об'єкт тварини містить об'єкт abilities, що описує, які дії автентифікований користувач-партнер може виконувати з цією твариною. Це перший прапорець доступу; з часом будуть додані нові.
| Поле | Опис |
|---|---|
abilities.can_edit | Чи може автентифікований користувач-партнер редагувати цю тварину — оновлювати її дані, додавати процедури та керувати фотографіями. True, коли користувач зареєстрував тварину, має будь-який зв'язок із нею (animal_user_relation) або є активним членом організації, у реєстрі якої вона є (org_animals). |
Розширення (X-Eternity-Expand)
Необов'язковий заголовок, що містить JSON-масив ключів розширення (напр. ["owners"]). Кожен запитаний ключ вбудовує додаткове поле в кожен об'єкт тварини у відповіді; пропустіть заголовок, щоб отримати звичайну картку. Невідомі ключі відхиляються з 422.
| Ключ | Додає | Опис |
|---|---|---|
owners | owners[] | Власники тварини — головний власник плюс будь-які співвласники — кожен із контактними даними та прапорцем is_main_owner. Доступно лише на цьому інтерфейсі партнера. |
"owners": [
{
"user_gid": 90231,
"public_id": "V1StGXR8Z5jd",
"has_account": true,
"email": "jane@example.com",
"phone": "+380681234567",
"display_hint": "Ja*** D.",
"language": "uk",
"country_id": "804",
"external_owner_id": "crm-4471",
"is_main_owner": true
}
]| Поле | Опис |
|---|---|
owners[].public_id | Стабільний публічний ідентифікатор власника — передайте його в POST /animals owners[].public_id (версія API >= 2026-07-04). |
owners[].user_gid | Застарілий числовий ідентифікатор власника (прикріплення власника у старих версіях API). |
owners[].has_account | Чи має власник уже придатний для використання обліковий запис. |
owners[].email | Email, що зберігається для цього власника (null, якщо невідомий). |
owners[].phone | Телефон, що зберігається для цього власника (null, якщо невідомий). |
owners[].display_hint | Замасковане відображуване ім'я (без персональних даних). |
owners[].language | Бажана локаль. |
owners[].country_id | Доповнений нулями числовий код ISO 3166-1 у вигляді рядка (напр. "804"). |
owners[].external_owner_id | Ідентифікатор, який ВИ передали нам для цієї людини, або null, якщо не передавали. Обмежений вашою інтеграцією — ви ніколи не бачите, як ту саму людину називає інший партнер. |
owners[].is_main_owner | true для головного власника (animal_user_relation типу main_owner); false для співвласників. |
Статуси відповіді
| Статус | Значення |
|---|---|
200 | OK — масив (можливо, порожній). |
/v1/partner/animals/by-ownerПошук тварин за контактом власника. Завжди масив.▸Автентифікація: HMAC. Будь-який ключ партнера.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
email_or_phone | так | string | — | Точний email або телефон власника (одне поле; email визначається за форматом). Телефон спершу розв'язується до власника. |
Приклад відповіді
{ "payload": [ { "id": "8xK3pQzVnB7rL2qF", "nickname": "Барсік", "species": 3,
"species_public_id": "d49c523a-d7ff-41b4-9ab6-0d1d2ce20939",
"species_name": "Собака", "breed": "Labrador",
"breed_public_id": null, "breed_name": null } ] }| Поле | Опис |
|---|---|
species_public_id / breed_public_id | Канонічні ключі — ті самі, що приймає POST /animals. breed_public_id порожній, доки у тварини лише текстова порода. |
species_name / breed_name | Назви мовою запиту (фолбек — англійська, далі латинська/канонічна назва). |
Дозволи
Кожен об'єкт тварини містить об'єкт abilities, що описує, які дії автентифікований користувач-партнер може виконувати з цією твариною. Це перший прапорець доступу; з часом будуть додані нові.
| Поле | Опис |
|---|---|
abilities.can_edit | Чи може автентифікований користувач-партнер редагувати цю тварину — оновлювати її дані, додавати процедури та керувати фотографіями. True, коли користувач зареєстрував тварину, має будь-який зв'язок із нею (animal_user_relation) або є активним членом організації, у реєстрі якої вона є (org_animals). |
Розширення (X-Eternity-Expand)
Необов'язковий заголовок, що містить JSON-масив ключів розширення (напр. ["owners"]). Кожен запитаний ключ вбудовує додаткове поле в кожен об'єкт тварини у відповіді; пропустіть заголовок, щоб отримати звичайну картку. Невідомі ключі відхиляються з 422.
| Ключ | Додає | Опис |
|---|---|---|
owners | owners[] | Власники тварини — головний власник плюс будь-які співвласники — кожен із контактними даними та прапорцем is_main_owner. Доступно лише на цьому інтерфейсі партнера. |
"owners": [
{
"user_gid": 90231,
"public_id": "V1StGXR8Z5jd",
"has_account": true,
"email": "jane@example.com",
"phone": "+380681234567",
"display_hint": "Ja*** D.",
"language": "uk",
"country_id": "804",
"external_owner_id": "crm-4471",
"is_main_owner": true
}
]| Поле | Опис |
|---|---|
owners[].public_id | Стабільний публічний ідентифікатор власника — передайте його в POST /animals owners[].public_id (версія API >= 2026-07-04). |
owners[].user_gid | Застарілий числовий ідентифікатор власника (прикріплення власника у старих версіях API). |
owners[].has_account | Чи має власник уже придатний для використання обліковий запис. |
owners[].email | Email, що зберігається для цього власника (null, якщо невідомий). |
owners[].phone | Телефон, що зберігається для цього власника (null, якщо невідомий). |
owners[].display_hint | Замасковане відображуване ім'я (без персональних даних). |
owners[].language | Бажана локаль. |
owners[].country_id | Доповнений нулями числовий код ISO 3166-1 у вигляді рядка (напр. "804"). |
owners[].external_owner_id | Ідентифікатор, який ВИ передали нам для цієї людини, або null, якщо не передавали. Обмежений вашою інтеграцією — ви ніколи не бачите, як ту саму людину називає інший партнер. |
owners[].is_main_owner | true для головного власника (animal_user_relation типу main_owner); false для співвласників. |
Статуси відповіді
| Статус | Значення |
|---|---|
200 | OK — масив (порожній, якщо у власника немає email у записі для пошуку лише за телефоном). |
422 | email_or_phone є обов'язковим. |
/v1/partner/animals/{id}Повна картка тварини.▸Автентифікація: HMAC. Будь-який ключ партнера.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
id | так | path string | — | Публічний ідентифікатор тварини (NanoID). |
Приклад відповіді
{ "payload": { "id": "8xK3pQzVnB7rL2qF", "species": 3,
"species_public_id": "d49c523a-d7ff-41b4-9ab6-0d1d2ce20939", "species_name": "Собака",
"breed": "Labrador", "breed_public_id": null, "breed_name": null,
"nickname": "Барсік", "microchip": "900263000123456", "deceased": false,
"abilities": { "can_edit": true } } }| Поле | Опис |
|---|---|
species_public_id | Канонічний public_id виду — той самий ключ, який ви передаєте назад як species_public_id у POST /animals. |
species_name | Назва виду мовою запиту (фолбек — англійська, далі латинська назва). |
breed_public_id | Канонічний public_id породи або null, якщо у тварини лише текстова порода. |
breed_name | Канонічна назва породи мовою запиту; null, коли breed_public_id порожній — тоді читайте `breed`. |
Дозволи
Кожен об'єкт тварини містить об'єкт abilities, що описує, які дії автентифікований користувач-партнер може виконувати з цією твариною. Це перший прапорець доступу; з часом будуть додані нові.
| Поле | Опис |
|---|---|
abilities.can_edit | Чи може автентифікований користувач-партнер редагувати цю тварину — оновлювати її дані, додавати процедури та керувати фотографіями. True, коли користувач зареєстрував тварину, має будь-який зв'язок із нею (animal_user_relation) або є активним членом організації, у реєстрі якої вона є (org_animals). |
Розширення (X-Eternity-Expand)
Необов'язковий заголовок, що містить JSON-масив ключів розширення (напр. ["owners"]). Кожен запитаний ключ вбудовує додаткове поле в кожен об'єкт тварини у відповіді; пропустіть заголовок, щоб отримати звичайну картку. Невідомі ключі відхиляються з 422.
| Ключ | Додає | Опис |
|---|---|---|
owners | owners[] | Власники тварини — головний власник плюс будь-які співвласники — кожен із контактними даними та прапорцем is_main_owner. Доступно лише на цьому інтерфейсі партнера. |
"owners": [
{
"user_gid": 90231,
"public_id": "V1StGXR8Z5jd",
"has_account": true,
"email": "jane@example.com",
"phone": "+380681234567",
"display_hint": "Ja*** D.",
"language": "uk",
"country_id": "804",
"external_owner_id": "crm-4471",
"is_main_owner": true
}
]| Поле | Опис |
|---|---|
owners[].public_id | Стабільний публічний ідентифікатор власника — передайте його в POST /animals owners[].public_id (версія API >= 2026-07-04). |
owners[].user_gid | Застарілий числовий ідентифікатор власника (прикріплення власника у старих версіях API). |
owners[].has_account | Чи має власник уже придатний для використання обліковий запис. |
owners[].email | Email, що зберігається для цього власника (null, якщо невідомий). |
owners[].phone | Телефон, що зберігається для цього власника (null, якщо невідомий). |
owners[].display_hint | Замасковане відображуване ім'я (без персональних даних). |
owners[].language | Бажана локаль. |
owners[].country_id | Доповнений нулями числовий код ISO 3166-1 у вигляді рядка (напр. "804"). |
owners[].external_owner_id | Ідентифікатор, який ВИ передали нам для цієї людини, або null, якщо не передавали. Обмежений вашою інтеграцією — ви ніколи не бачите, як ту саму людину називає інший партнер. |
owners[].is_main_owner | true для головного власника (animal_user_relation типу main_owner); false для співвласників. |
Статуси відповіді
| Статус | Значення |
|---|---|
200 | OK. |
404 | Тварину не знайдено. |
/v1/partner/animals/{id}Оновити змінювані поля / позначити як померлу.▸Автентифікація: HMAC. Власник АБО ветеринар з активним зв'язком із твариною. · X-Eternity-Idempotency-Key обов'язково
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
nickname | ні | string | — | Нова кличка. |
color | ні | string | — | Новий колір (вільний текст — без словника). |
sterilization_status | ні | bool | — | Встановити прапорець стерилізації. |
deceased | ні | bool | — | true → позначити тварину мертвою. |
Тіло запиту (JSON)
{
"nickname": "Барсік",
"color": "black",
"sterilization_status": true,
"deceased": false
}Приклад відповіді
204 No Content
Статуси відповіді
| Статус | Значення |
|---|---|
204 | Оновлено. |
403 | Немає доступу до цієї тварини — запросіть його (POST /v1/partner/animals/{id}/access-request) і повторіть після погодження власником. |
409 | Конфлікт X-Eternity-Idempotency-Key. |
422 | Помилка валідації. |
/v1/partner/animals/{id}/access-requestПопросити власника тварини надати вам доступ.▸Автентифікація: HMAC. Ключ ветеринара/організації. · X-Eternity-Idempotency-Key обов'язково
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
id | так | path string | — | Публічний ідентифікатор тварини (NanoID). |
Приклад відповіді
{
"payload": {
"status": "pending",
"requested_at": "2026-06-23T09:00:00+00:00",
"expires_at": "2026-06-30T09:00:00+00:00",
"retry_after_seconds": 604800
}
}| Поле | Опис |
|---|---|
status | "granted" — ви вже маєте доступ, запит не створено; "pending" — очікування на власника; "denied" — власник відхилив (можна переглянути повторно, доки термін не сплине). |
requested_at | Коли було створено запит (null, коли status="granted"). |
expires_at | Коли термін дії запиту спливає і ви можете запросити знову (null, коли status="granted"). |
retry_after_seconds | Секунди до того, як ви зможете знову запросити ту саму тварину (0, щойно сплине; null, коли status="granted"). |
Статуси відповіді
| Статус | Значення |
|---|---|
201 | Створено новий запит доступу — власника сповіщено електронною поштою. |
200 | Новий запит не створено: ви вже маєте доступ (status "granted"), або вже існує активний запит (status "pending"/"denied") — зачекайте retry_after_seconds перед повторним запитом. |
404 | Тварину не знайдено. |
/v1/partner/animals/{id}/access-requestПеревірити, чи погоджено ваш запит на доступ.▸Автентифікація: HMAC. Ключ ветеринара/організації.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
id | так | path string | — | Публічний ідентифікатор тварини (NanoID). |
Приклад відповіді
{
"payload": {
"status": "granted",
"requested_at": "2026-06-23T09:00:00+00:00",
"expires_at": "2026-06-30T09:00:00+00:00",
"retry_after_seconds": 0
}
}| Поле | Опис |
|---|---|
status | "granted" — доступ схвалено та він активний; "pending" — очікування на власника; "denied" — відхилено; "none" — немає активного запиту. |
Статуси відповіді
| Статус | Значення |
|---|---|
200 | OK. |
404 | Тварину не знайдено. |
/v1/partner/animals/{id}/proceduresЗапис процедур; відкриває прийом. Один об'єкт або масив.▸Автентифікація: HMAC. Ключ ветеринара/організації з доступом до тварини. · X-Eternity-Idempotency-Key обов'язково
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
(body) | так | object | array | — | Один об'єкт процедури або їх масив (≤100). |
type | так | int | procedure_types | Ідентифікатор каталогу процедур: 10 вакцинація, 20 вакцинація від сказу, 30 ідентифікація транспондером, 40 ідентифікація токеном, 50 дегельмінтизація, 60 стерилізація, 70 евтаназія / засвідчення смерті. |
occurred_at | так | datetime | — | Коли виконано (ISO 8601). |
summary | ні | string | — | Примітка у вільному тексті. |
revaccination_date | ні | date | — | Перевизначити дату наступної вакцинації (вакцинації). |
type_specific_payload | ні | object | — | Поля за типом — валідуються на стороні сервера: 10/20 → {vaccine_name*, batch_number*}; 30 → {transponder_number* — 15 digits}; 40 → {token_number*}; 50 → {drug*, batch_number?, dose?}; 60 → {method?, anesthesia_type?}; 70 → {reason*, death_date*}. Для типу 30: якщо тварина вже має мікрочип, він зберігається — новий номер зберігається як додатковий ідентифікатор (other_identifiers тип 11) замість заміни чипа. |
Тіло запиту (JSON)
[
{
"type": 10,
"occurred_at": "2026-05-30T08:00:00+00:00",
"summary": "Annual shot",
"revaccination_date": "2027-05-30",
"type_specific_payload": {
"vaccine_name": "Nobivac",
"batch_number": "A123"
}
},
{
"type": 30,
"occurred_at": "2026-05-30T08:05:00+00:00",
"type_specific_payload": {
"transponder_number": "900263000123456"
}
}
]Приклад відповіді
{
"payload": {
"appointment_id": 7741,
"procedures": [
{ "id": 99001, "animal_id": "8xK3pQzVnB7rL2qF", "visit_id": 7741, "type": 10,
"occurred_at": "2026-05-30T08:00:00+00:00", "summary": "Annual shot", "revaccination_date": "2027-05-30",
"type_specific_payload": { "vaccine_name": "Nobivac", "batch_number": "A123" } }
]
}
}| Поле | Опис |
|---|---|
appointment_id | Візит, відкритий/використаний для цієї партії. |
procedures[] | Записані процедури — та сама картка, що й у GET списку/картки. |
procedures[].id | Ідентифікатор запису процедури. |
procedures[].type | Числовий id типу (довідник procedure_types). |
procedures[].type_specific_payload | Збережені дані, специфічні для типу. |
Статуси відповіді
| Статус | Значення |
|---|---|
201 | Зафіксовано; візит відкрито. |
403 | Немає доступу до цієї тварини — запросіть його (POST /v1/partner/animals/{id}/access-request) і повторіть після погодження власником. |
404 | Тварину не знайдено. |
409 | Конфлікт X-Eternity-Idempotency-Key. |
422 | Непідтримуваний тип, відсутній occurred_at або відсутні специфічні для типу поля. |
/v1/partner/animals/{id}/proceduresСписок процедур тварини. Завжди масив.▸Автентифікація: HMAC. Ключ ветеринара/організації.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
type | ні | int | procedure_types | Фільтрувати за ідентифікатором каталогу процедур. |
since | ні | datetime | — | Лише на цей час або після нього. |
until | ні | datetime | — | Лише на цей час або до нього. |
Приклад відповіді
{
"payload": [
{ "id": 99001, "animal_id": "8xK3pQzVnB7rL2qF", "visit_id": 7741, "type": 10,
"occurred_at": "2026-05-30T08:00:00+00:00", "summary": null, "revaccination_date": "2027-05-30",
"type_specific_payload": { "vaccine_name": "Nobivac", "batch_number": "A123" } }
]
}| Поле | Опис |
|---|---|
type | Ідентифікатор каталогу процедур (словник procedure_types). |
visit_id | Прийом, під яким зафіксовано процедуру. |
type_specific_payload | Поля за типом. |
Статуси відповіді
| Статус | Значення |
|---|---|
200 | OK — масив (можливо, порожній). |
404 | Тварину не знайдено. |
/v1/partner/procedures/{id}Одна процедура.▸Автентифікація: HMAC. Ключ ветеринара/організації.
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
id | так | path int | — | Ідентифікатор запису процедури. |
Приклад відповіді
{
"payload": {
"id": 99001, "animal_id": "8xK3pQzVnB7rL2qF", "visit_id": 7741, "type": 10,
"occurred_at": "2026-05-30T08:00:00+00:00", "summary": null, "revaccination_date": "2027-05-30",
"type_specific_payload": { "vaccine_name": "Nobivac", "batch_number": "A123" }
}
}Статуси відповіді
| Статус | Значення |
|---|---|
200 | OK. |
404 | Процедуру не знайдено. |
/v1/partner/animals/{id}/photosЗавантажити фото (multipart). Власник або ветеринар зі звʼязком.▸Автентифікація: HMAC + multipart/form-data. Власник АБО ветеринар зі зв'язком. · X-Eternity-Idempotency-Key обов'язково
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
file | так | file | — | Файл зображення. Макс. 8 MB на фото (config partner.photos.max_single_mb). |
kind | ні | enum | — | avatar | gallery | nose_print. avatar встановлює головне фото. За замовчуванням gallery. |
Приклад відповіді
{ "payload": { "id": 33015 } }| Поле | Опис |
|---|---|
id | Ідентифікатор нового фото. |
Статуси відповіді
| Статус | Значення |
|---|---|
201 | Завантажено. |
403 | Немає доступу до цієї тварини — запросіть його (POST /v1/partner/animals/{id}/access-request) і повторіть після погодження власником. |
422 | Недійсний файл або більший за 8 MB (зменшіть розмір / знизьте якість). |
413 | Увесь запит перевищує 15 MB. |
/v1/partner/animals/{id}/photos/{photoId}М'яке видалення фото.▸Автентифікація: HMAC. Власник АБО ветеринар зі зв'язком. · X-Eternity-Idempotency-Key обов'язково
Поля запиту
| Поле | Обов. | Тип | Словник | Опис |
|---|---|---|---|---|
id | так | path string | — | Публічний ідентифікатор тварини (NanoID). |
photoId | так | path int | — | Ідентифікатор фото. |
Приклад відповіді
204 No Content
Статуси відповіді
| Статус | Значення |
|---|---|
204 | Видалено. |
403 | Немає доступу до цієї тварини — запросіть його (POST /v1/partner/animals/{id}/access-request) і повторіть після погодження власником. |