↑↓ вибірEnter відкритиEsc закрити

    1. Elbuz
    2. Керівництво користувача Elbuz
    3. AI-агенти, MCP і API

    API v2: ключ від імені співробітника, списки, зміни й помилки

    17 хв читанняОновлено

      API v2 дає вашій програмі доступ до каталогу, прайсів, клієнтів, документів, угод і органайзера Elbuz з правами одного співробітника: запит бачить і змінює рівно те, що цей співробітник у вікнах. Зміни за замовчуванням чекають підтвердження в «Пульсі».

      Коли це знадобиться:

      • Сайт має забирати ціни й залишки — список змінених товарів читається курсором без пропусків.
      • Замовлення з сайту мають падати в Elbuz — повтор після обриву зв'язку не створить дубль.
      • Підрядник править дані — кожна його зміна приходить у «Пульс» як «було → стане».
      • Інтеграції треба бачити не все — ключ отримує вікна, поля й «Чиї дані» свого співробітника.

      З чого почати: видайте ключ у вікні «API та токени доступу».

      Що вміє API v2

      Де це і хто має доступ

      Меню
      Кабінет → Налаштування системи → «Інші налаштування» → плитка «API та токени доступу»
      Адреса API
      https://<ваш-домен>/api/v2/
      Право доступу
      вікно «API та токени доступу»; ключ іншому співробітнику — ще доступ до вікна користувачів
      Режим «Робити самому»
      вмикає лише «Управління»
      Підготувати
      співробітника з тими правами, які має отримати інтеграція

      Як видати ключ і що він бачить

      1. У вікні «API та токени доступу» натисніть «+». Відкриється картка нового ключа.
      2. У полі «Від імені співробітника» оберіть, чиї права отримає ключ. Список співробітників видно лише тому, у кого є доступ до вікна користувачів; решта видає ключ тільки на себе.
      3. Поле «Користувач» — назва ключа. Вона стоїть у заголовках заявок «Пульсу» («Ключ «site_sync»: змінити товар…»), тож назвіть ключ так, щоб було зрозуміло, чия це інтеграція.
      4. Новий ключ створюється з позначкою «Тільки для читання». Якщо інтеграція має щось змінювати — зніміть її.
      5. Натисніть «Створити ключ» і скопіюйте значення з поля «Новий ключ» кнопкою «Копіювати».
      Картка ключа API v2: від імені співробітника, режим змін, запобіжник і новий ключ
      1Від імені співробітника
      2Зміни даних
      3Запобіжник: змін на годину
      4Новий ключ
      5Тільки для читання
      1. Від імені співробітника — чиї права й «Чиї дані» отримає ключ. Інших співробітників тут бачить лише той, у кого є доступ до вікна користувачів.
      2. Зміни даних — «Питати» (кожна зміна чекає в «Пульсі») або «Робити самому». Перемикає лише «Управління».
      3. Запобіжник — після стількох виконаних змін за годину ключ сам повертається в «Питати».
      4. Новий ключ показується один раз: скопіюйте його кнопкою «Копіювати» до закриття вікна.
      5. Тільки для читання — у нового ключа ввімкнено; зніміть, якщо ключу треба щось змінювати.

      Ключ показується один раз. У базі зберігається тільки його відбиток (SHA-256) і перші вісім символів після elbz_ — за ними ви впізнаєте ключ у списку («elbz_6caef5fd_…»). Загубили — натисніть «Створити новий ключ»: старий перестане діяти в ту ж секунду, тож оновіть його в інтеграції одразу.

      Решта полів картки діють на кожному запиті, без перевидачі ключа: зняли «Активність» — наступний запит отримає 401; «Дата закінчення доступу» — ключ працює по цю дату включно; «IP-адреси для доступу» — перелік через кому, пробіл або з нового рядка, порожньо — звідусіль.

      Що бачить ключ

      Запит виконується так, ніби співробітник відкрив відповідне вікно. Тому:

      • Ресурс доступний, якщо співробітнику відкрите його вікно: товари — вікно товарів, документи — будь-яке з вікон документів. Немає вікна — ресурсу немає ні в описі, ні в списках (404).
      • Поле, закрите групі співробітника на перегляд (наприклад, «Ціна собівартість» price_cost), у відповіді відсутнє зовсім, фільтрувати за ним не можна. Поле, яке групі співробітника заборонено змінювати, — 422 при записі: у errors біля поля стоїть причина, для товару — «Змінювати це поле заборонено».
      • «Чиї дані» діють так само, як у вікні: менеджер із «Тільки свої» отримає лише своїх клієнтів і свої документи; чужий запис за id — 404.
      • Кнопки вікна: створення, видалення, проведення документа перевіряються за правами на відповідні кнопки.

      Окремих «скоупів» у ключа немає. Щоб звузити інтеграцію, видайте ключ співробітнику з вужчими правами — наприклад, заведіть користувача у відділі, якому відкрите лише вікно замовлень.

      Перший запит і формат відповіді

      curl -s "https://<ваш-домен>/api/v2/products?limit=2&fields=product_id,name,price,quantity" \
        -H "Authorization: Bearer elbz_xxxxxxxx_…"

      Відповідь (демо-акаунт, 14.10.2026):

      {"data":[
        {"product_id":1,"price":"4536","quantity":100,"name":"Marshall Willen Black and Brass (1006059)"},
        {"product_id":2,"price":"0","quantity":0,"name":"ADATA 16 GB DDR4 3600 MHz XPG Spectrix D41 RGB Tungsten Gray (AX4U360016G18I-ST41)"}],
       "has_more":true,
       "next_cursor":"eyJrIjoiMiIsImgiOiJiZTExNWY1MSJ9"}

      Формат однаковий для всіх ресурсів: список — {"data":[…],"has_more":…,"next_cursor":…}, один запис — {"data":{…}}. Значення приходять так:

      • id, посилання на інші записи, кількості й лічильники — числами;
      • позначки на кшталт flag_export — true/false;
      • гроші й міри — десятковим рядком ("4536");
      • зовнішні коди (sku, uuid, штрихкоди) — рядком;
      • дати — у форматі RFC 3339 зі зміщенням часового поясу ("2026-10-14T12:42:59+02:00").

      Параметр fields= працює і для списку, і для одного запису (GET /products/2?fields=product_id,sku,price). Заголовок Accept-Language: uk перемикає мову назв полів у описі ресурсів.

      Повний опис усіх ресурсів, полів і методів — GET /api/v2/openapi.json (OpenAPI 3.1) з тим самим ключем; без ключа — 401. Опис будується під права власника ключа: ресурсів і полів, яких співробітник не бачить, у ньому немає. Короткий перелік — GET /api/v2/: для кожного ресурсу операції, дії й поля з позначками filter, sort, write.

      Як читати списки: фільтри, сортування, курсор

      ПараметрЩо робить
      limitрозмір сторінки, за замовчуванням 50, найбільше 200
      fields=product_id,nameзалишити у відповіді лише ці поля списку
      filter[поле]=значеннядорівнює
      filter[поле][оператор]=значенняоператори ne, gt, gte, lt, lte, like (містить)
      filter[updated_since]=2026-10-01змінені від дати — те саме, що filter[date_modified][gte]
      sort=-quantityсортування за одним полем; мінус — за спаданням. Друге поле через кому ігнорується
      q=швидкий текстовий пошук (товари)
      cursor=значення next_cursor з попередньої сторінки

      Фільтрувати й сортувати можна лише за полями з позначкою filter / sort в описі ресурсу. Невідоме поле — 400 з поясненням: {"errors":{"nosuch":"not filterable"}}.

      Як працює курсор. Без sort записи йдуть за зростанням id, і курсор запам'ятовує останній id: нові записи, що з'явилися під час обходу, не зсувають сторінки. З sort курсор запам'ятовує номер сторінки, і запис, який під час обходу змінив позицію в сортуванні, може трапитися двічі або випасти. Для синхронізації беріть варіант без sort.

      Курсор прив'язаний до фільтрів і сортування запиту: змінили їх і передали старий курсор — 400 cursor does not match the query. Кінець списку — "has_more":false і "next_cursor":null.

      Довідники (currencies, warehouses, document_statuses та інші) віддаються цілком, до 500 рядків, без курсора. Рядки документа — лише разом із документом: GET /api/v2/document_items?filter[document_id]=123; без фільтра — 400.

      curl -s -g "https://<ваш-домен>/api/v2/products?filter[quantity][gt]=5&fields=product_id,name,quantity&limit=100" \
        -H "Authorization: Bearer elbz_…"

      Що стається із запитом на зміну

      ЗапитЩо робить
      POST /api/v2/{ресурс}створити запис
      PATCH /api/v2/{ресурс}/{id}змінити передані поля (решта не чіпаються)
      DELETE /api/v2/{ресурс}/{id}перемістити в кошик — тільки там, де в ресурсу є кошик
      POST /api/v2/{ресурс}/{id}/{дія}дія: провести документ, об'єднати дублі, запустити вивантаження тощо

      Що станеться із запитом, вирішує поле «Зміни даних» у картці ключа.

      «Питати (через «Пульс»)» — значення за замовчуванням. Elbuz перевіряє запит правами власника ключа (ресурс, поле, кнопку, «Чиї дані») і, якщо все гаразд, нічого не змінює, а ставить заявку в «Пульс». Інтеграція отримує 202 Accepted і адресу, де стежити за рішенням:

      HTTP/1.1 202 Accepted
      Location: /api/v2/approvals/3629
      
      {"data":{"status":"pending","approval_id":3629}}

      Заявку бачать співробітники з доступом до вікна ключів API: назва ключа, що він хоче зробити, і старе й нове значення кожного поля.

      Заявки ключа API в «Пульсі»: створити контрагента і змінити ціну товару
      1Зміна через API / MCP
      2Що саме зміниться
      3Прийняти
      4Відхилити
      5Прийняти всі від цього ключа
      6Прийняти й надалі робити самому
      1. Зміна через API / MCP — заявка ключа; у заголовку — імʼя ключа і що він хоче зробити.
      2. Рядки під заголовком — поле: було → стане (при створенні — заповнені поля).
      3. Прийняти — зміна виконується одразу, а ключ отримає результат у GET /api/v2/approvals/<id>.
      4. Відхилити — нічого не змінюється, заявка отримує статус rejected.
      5. Прийняти всі від цього ключа — по черзі виконує всі заявки, що чекають від цього ключа; режим ключа не змінюється.
      6. Прийняти й надалі робити самому — виконує заявку й перемикає ключ у «Робити самому» (лише «Управління»).

      GET /api/v2/approvals/3629 повертає status: pending — чекає, approved — прийнято й виконано (у result — запис після зміни), auto — виконано без людини в режимі «Робити самому», rejected — відхилено, нічого не змінено, error — прийнято, але виконати не вдалося, undone — зміну скасовано у «Що зробив AI». Ключ бачить лише свої заявки.

      «Робити самому» — зміна виконується одразу: створення відповідає 201 із заголовком Location, правка — 200 із записом після зміни (в обох — ще й approval_id), видалення — 204 без тіла.

      Кожна зміна все одно записується в «Пульс» зі статусом «AI зробив сам» і видна у вкладці «Що зробив AI», звідки її можна скасувати. Увімкнути «Робити самому» може лише «Управління».

      Запобіжник. Якщо ключ у «Робити самому» за годину виконав стільки змін, скільки вказано в полі «Запобіжник: змін на годину» (за замовчуванням 500), наступна зміна вже не виконується: ключ сам перемикається на «Питати», а в «Пульсі» з'являється пропозиція «Ключ «…» зробив N змін за годину й поставлений на паузу — продовжити без підтвердження?».

      Поки її не прийняли, усі зміни ключа йдуть заявками (202).

      Незалежно від режиму ключа: відповідь клієнту на лист (/mail_messages/{id}/reply) і повідомлення в чат (/chats/{id}/send) стають заявкою «Пульсу» свого типу — як листи, які готує сам AI Elbuz. Вони чекають людину, доки «Управління» не ввімкнуло для цього типу «Робити самому» у вкладці «Довіра» і лист пропустив AI-«Контролер».

      • Ключ із «Тільки для читання» на будь-який запис отримує 403.
      • Власні підписки на вебхуки ключ змінює сам, без заявок.
      Шлях запиту на зміну: перевірка правами — завжди; далі режим ключа вирішує, виконати зараз чи поставити заявку
      такнінітактакніПитатиРобити самомутакніЗапит POST, PATCH або DELETEКлюч «Тільки для читання»?403, нічого не зміненоПрава власника ключадозволяють?403, 404 або 422 з причиноюЛист або повідомлення клієнту?Заявка в «Пульсі», відповідь 202Режим ключаЗапобіжник за годину вичерпано?Ключ переходить у «Питати», у«Пульсі» пропозиція продовжитиВиконано одразу: 200, 201 або204, запис у «Що зробив AI»
      • Початок або кінець
      • Дія або результат
      • Розвилка: далі шлях залежить від відповіді

      Що можна скасувати

      Кнопка скасування в «Що зробив AI» є для: правки полів будь-якого ресурсу (повертає попередні значення), створення й видалення контрагента, документа, угоди, задачі, нотатки, проєкту, статті (через кошик), проведення й скасування проведення, позначки «виконано» в задачі.

      Правку полів скасування не поверне, якщо ці поля вже змінили після API, — відповідь «скасуйте вручну». Кнопки немає для створення товару, категорії, виробника, атрибута, групи атрибутів, групи контрагентів і дотику (у них немає кошика), для об'єднання дублів, переміщення угоди на етап і запуску фонових задач.

      Як не створити дубль: Idempotency-Key

      Кожен POST (створення й дії) зобов'язаний мати заголовок Idempotency-Key — будь-який унікальний рядок до 255 символів, наприклад . Без нього — 400. Відповідь зберігається 24 години: повтор із тим самим ключем і тим самим тілом не створює дубль, а повертає збережену відповідь із заголовком Idempotent-Replayed: true. Той самий ключ з іншим тілом — 422.

      curl -s -X POST "https://<ваш-домен>/api/v2/contractors" \
        -H "Authorization: Bearer elbz_…" -H "Content-Type: application/json" \
        -H "Idempotency-Key: order-sync-2026-10-14-0001" \
        -d '{"name":"ТОВ «Тест API»","email":"test-api@example.com"}'

      Помилкова відповідь (400, 422) теж запам'ятовується під цим ключем. Виправили тіло — беріть новий Idempotency-Key, інакше отримаєте 422 «Idempotency-Key was used with another request». Не зберігаються лише 429 і помилки сервера.

      Помилки й ліміти

      Помилки приходять у форматі RFC 9457 (application/problem+json) зі справжнім кодом HTTP:

      {"type":"https://elbuz.com/problems/unprocessable","title":"Unprocessable","status":422,
       "detail":"some fields cannot be written","errors":{"date_modified":"not writable"}}
      КодtypeКоли
      400bad_requestнемає Idempotency-Key, тіло не JSON-об'єкт, фільтр за невідомим полем, чужий курсор
      401unauthorizedнемає заголовка, ключ неправильний, вимкнений або прострочений, співробітник-власник неактивний
      403forbiddenадреса не в «IP-адреси для доступу», ключ «Тільки для читання», немає права на кнопку
      404not_foundресурсу немає або його вікно закрите, запис не видно за «Чиї дані»
      405method_not_allowedоперації в ресурсу немає — наприклад, DELETE /products/2
      409conflictтакий запис уже існує (наприклад, контрагент із тими самими даними) — у errors його id
      422unprocessableполе не можна записати, посилання на невидимий запис, повтор Idempotency-Key з іншим тілом
      429rate_limitedперевищено ліміт запитів

      Кожна відповідь має заголовок X-Request-Id — назвіть його підтримці, і запит знайдуть у журналі.

      Ліміт — 120 запитів за ковзну хвилину на ключ (більше — лише якщо підтримка підняла ліміт цьому ключу); запити MCP-асистента тим самим ключем рахуються в той самий ліміт. Залишок видно в заголовках кожної відповіді: RateLimit-Policy: "default";q=120;w=60 і RateLimit: "default";r=119;t=60 (r — скільки лишилося, t — секунд до звільнення). На 429 прийде Retry-After — зачекайте вказані секунди.

      Чому 422 після PATCH, а частина полів уже записана

      У товарів, виробників, контрагентів, документів і угод поля записуються по одному тим самим шляхом, що й правка клітинки в сітці вікна; у решти ресурсів — одним викликом функції збереження. Поле, якого немає в описі ресурсу, службове або закрите правами, відхиляється до запису всього запиту — 422 з переліком полів.

      Якщо ж у ресурсу з правкою по полю одне поле відхилила перевірка самої програми (недопустиме значення або заборона групі змінювати поле — «Змінювати це поле заборонено»), відповідь теж 422, але інші поля з того самого запиту вже записані: перечитайте запис GET, перш ніж повторювати.

      Які ресурси є

      Набір нижче — для співробітника з повним доступом; ключ отримує лише ті, чиї вікна відкриті власнику.

      РесурсОпераціїДії
      productsсписок, запис, створення, правка—
      categories, manufacturersсписок, запис, створення, правкаmerge
      attributesсписок, запис, створенняmerge
      attribute_groupsсписок, запис, створення—
      supplier_products (рядки прайсів)список, запис—
      contractorsусе, видалення — у кошикmerge
      companies, contractor_groupsсписок, запис (групи — ще створення й правка)—
      documents (+ document_items)усе, видалення — у кошикsign, unsign
      orders (замовлення покупців)список, записPOST /orders/sync — замовлення вашого магазину пакетом до 100: створити нові й оновити завантажені, докладно
      deals, pipelinesугоди — усе, видалення в кошик; воронки — списокmove_stage
      tasks, notes, projectsусе, видалення — у кошикdone, reopen
      touches (дотики в календарі)список, запис, створення, правка—
      mail_messages, chats, chat_messages, callsлише читанняreply, send — завжди через «Пульс»
      pulse_itemsсписок, записaccept, reject, accept_trust, undo
      usersлише читання, без паролів і ключів входу—
      articlesусе, видалення — у кошик—
      price_lists, export_templates, flowsсписок, записimport / run — фонова задача
      import_templates, jobs, sales_reportлише читання—
      webhooks, webhook_deliveriesвебхуки цього ключа—
      довідники: document_types, document_statuses, payment_statuses, delivery_statuses, payment_types, delivery_types, stock_statuses, warehouses, stores, currencies, languagesлише читання, цілим списком—

      Дії з фоновою задачею (/price_lists/{id}/import, /export_templates/{id}/run, /flows/{id}/run) відповідають {"data":{"status":"queued","job_id":…}}, у режимі «Питати» — спершу 202 і заявкою в «Пульсі»; хід роботи — GET /api/v2/jobs/{id}. Агрегати («скільки замовлень за статусами», «сума продажів по менеджерах») — GET /api/v2/query?spec={…}; перелік сутностей і полів — ?spec={"describe":true}.

      Позиції документа: товар за product_id або за назвою

      Позиції документа передаються в POST /api/v2/documents масивом item_list. Позиція без product_id, але з name, теж записується — Elbuz сам підбирає їй товар:

      • спершу шукає за штрихкодом ean, потім за артикулом sku, потім за точною назвою. Назва порівнюється без урахування регістру, зайвих пробілів і лапок і зараховується, лише якщо товар із такою назвою в базі один;
      • не знайшов — створює новий товар з назвою, артикулом, штрихкодом і ціною позиції в службовій категорії «Товари - api_v2 - …». Документ, який MCP-асистент або AI-агент у браузері створює без підтвердження в «Пульсі», кладе нові товари в «Товари - mcp - …» або «Товари - ai - …». Категорія створюється вимкненою й без вивантаження.

      У документі не буває позицій без товару: позиція без product_id і без name не записується. product_id, якого немає в базі або який ключу не видно, — 422 до створення документа, у errors — "item_list.0.product_id": "not found" (номер — позиція в масиві).

      curl -s -X POST "https://<ваш-домен>/api/v2/documents" \
        -H "Authorization: Bearer elbz_…" -H "Content-Type: application/json" \
        -H "Idempotency-Key: order-1042" \
        -d '{"type_id":3,"contractor_id":15,"item_list":[
              {"product_id":2,"quantity":1,"price":"1890"},
              {"name":"Кабель HDMI 2.1, 2 м","sku":"HDMI-21-2M","ean":"4820000000017","quantity":3,"price":"250"}]}'

      Щоб товари не плодилися, передавайте в позиції product_id (його повертає GET /products), а якщо його у вас немає — хоча б ean або sku, такі самі, як у картці товару в Elbuz. Пошук за назвою спрацьовує лише на точний і єдиний збіг: інша назва в замовленні або два товари з однаковою назвою — і з'являється нова картка.

      Нові картки збираються в службових категоріях «Товари - api_v2 - …»: заглядайте туди, щоб помітити позиції, яких Elbuz не впізнав.

      Сценарії

      Сайт забирає залишки й ціни

      Ключ від імені співробітника, якому відкрите лише вікно товарів, з «Тільки для читання». Раз на 10 хвилин — GET /products?filter[updated_since]=…&fields=product_id,sku,price,quantity без sort, обхід курсором. Закупівельна ціна не потрапить у відповідь, якщо її поле закрите групі цього співробітника.

      Замовлення з сайту без дублів

      Ключ із режимом «Робити самому» від менеджера відділу продажів. Нові й змінені замовлення сайт шле пакетом у POST /orders/sync: Elbuz сам упізнає вже завантажене замовлення за його номером на сайті й оновить оплату, доставку й статус, не затираючи статус менеджера. Формат і правила — замовлення магазину через API.

      Підрядник править описи, а ви перевіряєте

      Ключ у режимі «Питати» від співробітника з правом на вікно товарів. Кожен PATCH приходить у «Пульс» рядком «Опис повний: … → …». Якщо правки добрі — «Прийняти всі від цього ключа»; якщо довіряєте — «Прийняти й надалі робити самому».

      Що робити, коли запит не проходить

      Розбір частих проблем
      Що ви бачитеЧому такЩо зробити
      401 «invalid, disabled or expired key»ключ перевипущено, вимкнено «Активність» або минула дата закінченняперевірте картку ключа (видати ключ)
      На PATCH приходить 202, а дані не змінилисьключ у режимі «Питати»прийміть заявку в «Пульсі» або перемкніть ключ (зміни)
      403 «read-only key»у нового ключа ввімкнено «Тільки для читання»зніміть позначку в картці ключа
      У відповіді немає поля, яке є у вікніполе закрите групі власника ключавідкрийте поле в правах групи або видайте ключ іншому співробітнику
      422 «Idempotency-Key was used with another request»той самий ключ ідемпотентності з іншим тіломновий Idempotency-Key (докладно)
      400 «cursor does not match the query»курсор від запиту з іншими фільтрамипочніть обхід без cursor

      Часті запитання

      Чи можна дати ключу доступ лише до замовлень?

      Так: видайте ключ від імені співробітника, якому відкрите лише вікно замовлень. Ключ отримує права окремо взятого співробітника — вікна, поля й «Чиї дані».

      Чому зміна через API повертає 202?

      Ключ у режимі «Питати»: зміна чекає підтвердження в «Пульсі». Статус — GET /api/v2/approvals/{id}. Щоб змінювати одразу, «Управління» перемикає ключ на «Робити самому».

      Скільки запитів на хвилину дозволено?

      120 за ковзну хвилину на ключ, разом із запитами MCP цим самим ключем. Залишок — у заголовку RateLimit, на 429 — Retry-After.

      Де опис усіх методів?

      GET https://<ваш-домен>/api/v2/openapi.json з ключем у заголовку. Опис складено під права власника ключа.

      Чи можна видалити товар через API?

      Ні. Через API в кошик видаляються лише контрагенти, документи, угоди, задачі, нотатки, проєкти й статті. Дублі контрагентів, категорій, виробників і атрибутів об'єднуються дією merge.

      Чи можна записати кілька записів одним запитом?

      Лише замовлення: POST /orders/sync приймає до 100 замовлень за запит. Решта записів — окремим запитом кожен; розраховуйте обсяг на 120 запитів за хвилину.

      Чи підходить до v2 старий api_token?

      Ні. api_token і вхід api/login працюють лише зі старим API. Як перевести інтеграцію — перехід на v2.

      Суміжні теми

      Чи була стаття корисною?

      Зміст статті

      Спробувати безкоштовно