Розділи документації API
Документація API/Запити/Списки, поля, одиниці

Списки, поля, одиниці

Спільні правила для всіх маршрутів: параметри списків, типи даних у JSON, як закодовані гроші й кількість, як працює оновлення.

Параметри списків

ПараметрЗа замовчуваннямЩо робить
page1Номер сторінки з 1. Значення менше 1 вважається за 1.
per-page20Розмір сторінки, максимум 100 (більше значення обрізається до 100). Пишеться через дефіс: per_page у запиті ігнорується.
orderidСортування: order=updated_at сортує за зростанням, order=-updated_at за спаданням. Одне поле.
fieldsусіЯкі колонки читати з бази, через кому.
expandнемаєПідтягнути пов’язані записи, через кому.
filter[...]немаєДив. розділ Фільтри.
is_archived=trueнемаєСховати архівні записи.

Відповідь списку

{
  "items": [ ... ],
  "total": 318,      // скільки записів за фільтрами всього
  "page": 2,
  "per_page": 100    // у відповіді — з підкресленням
}
  • ●Сторінка за межами повертає порожній items з правильним total, а не помилку.
  • ●Сторінок: ceil(total / per_page).
  • ●Деякі довідники (/lookup, /extra-fields, /account/our, /balance) віддають увесь перелік без total.
Помилка в параметрах дає 400, а не тишуНевідоме поле в order, fields чи filter, невідомий оператор або зв’язка фільтра повертають 400 bad_request з поясненням, напр. «Некоректний фільтр "filter[first_name;bogus]": невідомий оператор». Список без фільтра у відповідь на одруківку не повернеться.
Вивантаження всього без пропусківПоки ви гортаєте сторінки, записи додаються. Для повного вивантаження сортуйте за id і беріть filter[id;gt]=<останній id> замість збільшення page.

fields: лише потрібні колонки

GET /api/v1/contact?fields=id,first_name,last_name,updated_at&per-page=100
  • ●Працює для списків. Картка (GET /contact/42) fields ігнорує й повертає все.
  • ●Структура відповіді не скорочується: невибрані поля приходять порожніми значеннями свого типу ("", 0, null). Не сприймайте їх як «порожні в базі».
  • ●Назви такі самі, як у JSON (snake_case). На невідому назву буде 400.

expand: пов’язані записи

Назви зв’язків пишуться з великої літери, як у списку «Пов’язані об’єкти для ?expand=» на сторінці кожної сутності. Через кому; вкладеність через крапку, не глибше 2 рівнів.

GET /api/v1/order/85?expand=Contact,Account,Status
GET /api/v1/contact?expand=Owner,Account.Owner,Channels,ContactExtraFields
  • ●Без expand пов’язані об’єкти дорівнюють null, є лише їхні *_id.
  • ●Канали (Channels) і доп. поля (ContactExtraFields тощо) теж читаються лише з expand, і в картці, і в списку.
  • ●Невідома назва (owner з малої) або вкладеність глибше 2 рівнів дає 400 ще до запиту в базу.
  • ●Список з expand коштує 5 очок замість 2.
  • ●Права ролі діють і тут: зв’язок на сутність, закриту для перегляду (напр. Account при account.view = denied), приходить null; при «лише свої» підтягуються тільки записи, де користувач токена є відповідальним. Імена користувачів (Owner, CreatedBy) видно завжди.

Типи даних у JSON

Тип у документаціїУ JSONПриклад
idціле число або null42
цілеціле число3
рядокрядок; «≤ N симв.» означає максимальну довжину"Олена"
booltrue / falsetrue
дата-часрядок RFC 3339 з поясом або null"2026-10-01T14:32:01+03:00"
десяткове (рядок)рядок з крапкою, щоб не втрачати точність"41.250000"
числочисло з дробовою частиною12.5
ціле, копійкисума в мінімальних одиницях валюти150000
ціле, ×1000кількість з трьома знаками після коми2500
масив / об’єктвкладені даніВкладені дані

Позначка «лише читання» біля поля означає, що його рахує або ставить сервер (суми позицій, «сплачено», дати виграшу, номер при створенні тощо). У тілі POST/PUT такі поля ігноруються.

Гроші

Жодних дробівУсі суми передаються як цілі числа в мінімальних одиницях валюти: копійки для гривні, центи для долара. 150000 у гривнях = 1 500,00 грн.
  • ●Кількість знаків після коми у валюти показує поле MinorUnit у GET /currency (для UAH, USD, EUR це 2).
  • ●exchange_rate документа (замовлення, рахунку, угоди) означає курс його валюти до гривні, десяткове рядком. Фіксується на момент документа. У платежу курс інший, до валюти рахунку, див. Платежі.
  • ●personal_discount контакту чи контрагента задається відсотком, числом 0–100, а не копійками.

Перетворення

hryvnias = 150000 / 10 ** currency["MinorUnit"]   # 1500.00
kopecks  = round(1500.00 * 100)                    # 150000

Кількість і знижка в позиціях

ПолеКодуванняПриклад
quantityціле ×10001000 = 1 шт., 2500 = 2,5 кг
discountсоті частки відсотка1000 = 10 %
discount_amountкопійки5000 = 50,00

Товар без дробової кількості приймає лише кратне 1000, інакше поверне 422 «Для цього товару дозволена лише ціла кількість».

Дати

  • ●У відповідях дати йдуть у RFC 3339 з поясом: 2026-10-01T14:32:01+03:00.
  • ●У тілі запиту теж RFC 3339 (2026-10-01T10:00:00+03:00).
  • ●У фільтрах можна писати 2026-10-01, 2026-10-01 14:32:01 або RFC 3339 (час кабінету).

Створення й оновлення

POST

Тіло передається як JSON у UTF-8 із заголовком Content-Type: application/json. Відповідь 201 зі створеним записом. Поля «лише читання» ігноруються, так само як id, created_at, updated_at і deleted_at у тілі: ідентифікатор і дати ставить сервер.

PUT: часткове оновлення

  • ●Змінюються лише передані поля, решта лишається як була.
  • ●Вкладені масиви: якщо ключа немає, масив не змінюється; channels і tags замінюються повністю; доп. поля оновлюються за field_id. Деталі в розділі Вкладені дані.
  • ●Щоб очистити рядкове поле, передайте ""; щоб прибрати посилання, передайте null (напр. {"account_id": null}).
  • ●Одночасні PUT одного запису виконуються по черзі: правки різних полів не губляться, а для одного й того самого поля перемагає останній запит. Поле version службове.

DELETE

Відповідь 204 без тіла. Після видалення картка (GET /.../{id}) віддає 404. Контакти, контрагенти, ліди, угоди, завдання, товари, замовлення й рахунки видаляються «м’яко» і з’являються в /.../deleted, а платежі видаляються остаточно.

Службові поля у відповідях

У відповідях трапляються поля з великої літери (OldContact, OldOrder, PrimaryBarcode тощо) і поле sub. Це службові дані інтерфейсу, вони не стабільні. Ігноруйте їх.