Тема
Для розробника
Ця сторінка — для того, хто вбудовує агента у власний застосунок. Тут описано, коли API взагалі потрібен, які бувають ключі й з чого почати.
Шукаєте перелік ендпоїнтів?
Довідник API → — усі ендпоїнти платформи зі схемами, прикладами й кнопкою «спробувати»: розмова, віджет, агенти, хід, тригери, знання, дії, звернення, команда й тарифікація.
Коли API потрібен, а коли ні
Не потрібен, якщо ви:
- ставите агента на сайт готовим вікном — досить одного рядка коду, див. Де агент відповідає;
- підключаєте бота в Telegram — це робиться однією фразою в розмові з конструктором;
- наповнюєте знання сайтом або текстом — конструктор робить це сам, див. Що агент знає.
Потрібен, якщо ви:
- робите власний інтерфейс чату — у мобільному застосунку або на своєму сайті;
- приймаєте звернення у власній системі підтримки;
- синхронізуєте знання агента з каталогом чи базою з вашої системи автоматично;
- будите агента подіями зі своєї системи — це вхідний вебхук тригера.
Одна річ зараз можлива тільки через API
Майже все, що робить кабінет, робиться в розмові з конструктором або на екранах Розмови, Тариф і Команда. Через API — і поки що тільки через нього — лишився глибокий обхід сайту: до 50 сторінок за раз, тоді як у розмові стеля 40. Автоматичне перечитування сайту за розкладом просити не треба: воно вмикається само після першого обходу, і в розмові його можна переналаштувати або вимкнути. А сам конструктор доступний і агентам — через MCP та API.
Довідник
| Інтерактивний довідник | https://api.youselfbot.com/docs |
| Машинна специфікація | https://api.youselfbot.com/v1/openapi.json |
Довідник описує весь HTTP API, а не лише інтеграційні виклики: кабінет — це просто перший клієнт того самого API, тож усе, що вміє він, доступно й вам. Специфікація за другим посиланням придатна для генерації клієнта.
Ця сторінка пояснює, що там шукати.
Ключі
Агент має три ключі. Кожен можна взяти й із кабінету, і викликом.
| Ключ | Де береться | Де працює |
|---|---|---|
pk_… Публічний | у розмові: «дай код для сайту»; GET /v1/dashboard/bots/{id} | лише вікно чату у браузері |
sk_… Серверний | панель → рядок Канали → Новий ключ до API; POST /v1/dashboard/bots/{id}/secret | це API (/v1/api/*, /v1/admin/*) |
| Підтвердження відвідувача | панель → рядок Канали → Новий ключ підпису відвідувачів; POST /v1/dashboard/bots/{id}/identity-secret | підпис особи відвідувача на вашому сервері |
Обидва важелі в панелі перевипускають ключ, а не показують чинний: чинного не знає ніхто, зокрема й ми. Тому натискати їх варто лише тоді, коли старий ключ утік або загубився.
Публічний ключ для цього API не підходить: будь-який виклик /v1/api/* з pk_-ключем повертає 403 з кодом wrong_key_type — не 401. Ключ дійсний, просто не того типу. Це найчастіша помилка на старті.
Серверний ключ живе тільки на бекенді
Ніколи не показуйте sk_… у браузері, мобільному застосунку чи публічному репозиторії. Браузер із чужої сторінки до цих викликів і не дістанеться: дозволені лише домени кабінету.
Ключ повертається один раз
І серверний ключ, і ключ підтвердження відвідувача повертаються повністю лише у відповіді на запит випуску — далі система знає тільки їхній відбиток. Перевипуск ламає старий ключ негайно: усе, що ним користується, зупиниться, доки ви не пропишете новий.
Hello world
bash
KEY="sk_ваш_серверний_ключ"
BASE="https://api.youselfbot.com"
SESSION=$(uuidgen) # непередбачуваний id, один на діалог
curl -sS -X POST "$BASE/v1/api/chat" \
-H "X-Bot-Key: $KEY" -H "Content-Type: application/json" \
-d "{\"session_id\":\"$SESSION\",\"message\":\"Які у вас години роботи?\"}"
# {"answer":"Ми працюємо з 9:00 до 18:00, пн–пт.","session_id":"…"}Наступна репліка того самого діалогу — той самий session_id. Так агент пам'ятає контекст.
session_id — це ключ до розмови, а не її номер
Беріть його з uuidgen, crypto.randomUUID() чи іншого джерела криптографічної випадковості. Не user-42, не порядковий номер, не пошта клієнта.
Причина проста: хто знає session_id, той може читати цю розмову, писати в неї й прикріплювати до неї файли — і його побачить ваш оператор як повідомлення клієнта. Передбачуваний ідентифікатор робить це доступним будь-кому, хто вміє рахувати.
Ключ агента при цьому не рятує: публічний ключ віджета за побудовою лежить у розмітці вашої сторінки.
Розмова
| Виклик | Про що |
|---|---|
POST /v1/api/chat | одна репліка, відповідь повністю |
POST /v1/api/chat/stream | те саме, але потоком (SSE) — відповідь друкується на очах |
POST /v1/api/visitors/erase | видалити все, що зберігається про одного відвідувача |
Відповідь 200 на chat має три режими, і всі приходять із тим самим статусом: звичайна відповідь, "handoff": true (розмову веде людина) і "quota_exceeded": true (вичерпано ліміт). Перевіряйте прапорці явно.
Порожній answer не показуйте як репліку
Коли розмову веде людина, answer може бути порожнім: репліку просто переслано оператору. Це найчастіша помилка при першій інтеграції — у чаті з'являються порожні бульбашки від бота.
Передача людині
| Виклик | Про що |
|---|---|
POST /v1/api/handoff | клієнт просить оператора |
GET /v1/api/messages | забрати нові повідомлення оператора |
POST /v1/api/typing | «клієнт друкує…» для ваших операторів |
GET /v1/api/operator/threads | список звернень |
GET /v1/api/operator/threads/{sid} | повний транскрипт |
POST /v1/api/operator/threads/{sid}/reply | відповідь оператора |
POST /v1/api/operator/threads/{sid}/typing | «оператор друкує…» |
POST /v1/api/operator/threads/{sid}/resolve | завершити звернення |
bash
KEY="sk_ваш_серверний_ключ"
BASE="https://api.youselfbot.com"
SID="3f6c1b9e-7f42-4d2a-9a6f-0d5b1f0b21c7"
# Прочитати транскрипт звернення
curl -sS "$BASE/v1/api/operator/threads/$SID" -H "X-Bot-Key: $KEY"
# Відповісти клієнту
curl -sS -X POST "$BASE/v1/api/operator/threads/$SID/reply" \
-H "X-Bot-Key: $KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"text":"Вітаю! Перевіряю ваше замовлення, хвилинку."}'
# Показати клієнту «оператор друкує…»
curl -sS -X POST "$BASE/v1/api/operator/threads/$SID/typing" -H "X-Bot-Key: $KEY"
# Завершити — далі знову відповідає агент
curl -sS -X POST "$BASE/v1/api/operator/threads/$SID/resolve" -H "X-Bot-Key: $KEY"Відповідь оператора доходить до відвідувача в реальному часі. Ці виклики потрібні тим, у кого власна система підтримки: у кабінеті для тієї самої роботи є розділ Розмови — див. Коли клієнт просить живу людину.
Разом із вихідними вебхуками це дає повний цикл без полінгу. GET /v1/api/operator/threads корисний для початкової синхронізації або відновлення після простою.
Клієнтський бік: свій чат
Якщо у вас власний інтерфейс чату замість нашого вікна:
bash
# Клієнт просить оператора
curl -sS -X POST "$BASE/v1/api/handoff" \
-H "X-Bot-Key: $KEY" -H "Content-Type: application/json" \
-d "{\"session_id\":\"$SID\"}"
# {"status":"waiting"}
# Забрати нові повідомлення оператора
curl -sS "$BASE/v1/api/messages?session_id=$SID" -H "X-Bot-Key: $KEY"json
{
"messages": [
{ "id": "msg_…", "author": "operator", "text": "Вітаю!", "at": 1753600000123 }
],
"status": "operator",
"operator_typing": false,
"next_cursor": "…"
}- Перше опитування — без позиції. Далі передавайте
?cursor=зі значеннямnext_cursorпопередньої відповіді. - Старого параметра
afterбільше немає. Якщо надіслати його, сервер його просто не побачить і поверне стенограму з початку — тобто ті самі повідомлення вдруге. operator_typingзгасає сам приблизно через 6 секунд, тож просто перемальовуйте індикатор за значенням із кожного опитування.
Знання
| Виклик | Про що |
|---|---|
POST /v1/api/knowledge | навчити агента документом |
GET /v1/api/knowledge | перелічити джерела (з пагінацією) |
GET /v1/api/knowledge/{id} | прочитати джерело повністю |
DELETE /v1/api/knowledge/{id} | видалити джерело |
bash
curl -sS -X POST "$BASE/v1/api/knowledge" \
-H "X-Bot-Key: $KEY" -H "Content-Type: application/json" \
-d '{
"source_id": "catalog-item-4417",
"title": "Лампа Nord 40W",
"text": "Лампа Nord 40W. Ціна 1290 грн. Гарантія 24 місяці…"
}'source_id — ваш власний ідентифікатор. Той самий source_id оновлює джерело, а не додає друге. Саме це робить регулярну синхронізацію каталогу з вашої системи безпечною: ганяйте її хоч щогодини.
Усе, що додано так, агент бачить нарівні зі знаннями, які дав йому конструктор у розмові, — і навпаки.
Що треба знати заздалегідь
Ідемпотентність
Кожен виклик із побічним ефектом приймає заголовок Idempotency-Key. Повтор після таймауту не виконає дію вдруге — повернеться збережена відповідь першої спроби із заголовком Idempotency-Replayed: true. Ключ живе 24 години.
Це не опція «про всяк випадок»: без нього мережевий таймаут на POST .../reply може надіслати клієнту друге таке саме повідомлення.
Помилки
Кожна помилка — JSON із двома полями:
json
{ "error": "wrong key type: this endpoint needs a secret key (sk_)", "code": "wrong_key_type" }Розгалужуйтесь на code, не на error: текст може змінитися будь-коли. Перелік кодів поповнюється — незнайомий код обробляйте як загальну помилку відповідного HTTP-статусу, а не падайте.
«Не можна» і «не вийшло» — різні відповіді
401 і 403 кажуть про ваш ключ: він відсутній, недійсний або не того типу. Повторювати такий запит немає сенсу — відповідь буде та сама.
503 із кодом service_unavailable каже інше: ми не змогли виконати перевірку — сховище зараз недоступне. Ключ дійсний, повторіть за мить.
Плутати їх дорого саме в бік «не можна». Клієнт, який читає будь-яку невдачу як «доступ закрито», на короткому збої нашої бази викидає користувача на екран входу — тобто повідомляє йому, що його сесія скінчилась, хоч вона жива. Правило просте:
| Відповідь | Що робити клієнту |
|---|---|
401, 403 | показати вхід / перевірити ключ; повторювати не варто |
429 | зачекати до RateLimit-Reset і повторити |
503, 502 | повторити за мить із тим самим ключем |
5xx решта | повторити з відступом, потім здатися й сказати про це людині |
Ліміти запитів
60 запитів за хвилину на діалог і записи, 240 — на читання та сигнали. Вікно — одна хвилина, окремо на пару «ключ + IP».
Заголовки RateLimit-Limit, RateLimit-Remaining і RateLimit-Reset є на кожній відповіді, не лише на 429.
Версіонування
Префікс /v1 фіксує контракт. У його межах зміни лише адитивні: нові виклики, нові поля у відповідях, нові необов'язкові поля в запитах, нові значення code. Наявні поля не перейменовуються, не змінюють тип і не зникають.
Тому ваш клієнт мусить ігнорувати незнайомі поля й толерувати незнайомі значення переліків. Несумісна зміна = новий префікс, який працює паралельно.
Ідентифікатор запиту
Кожна відповідь містить X-Request-Id. Збережіть його у своїх логах — зі зверненням у підтримку він одразу вказує на потрібний запис у наших. Можна надіслати свій — тоді один ідентифікатор пройде наскрізь через ваші системи й наші.
Чого тут немає
Конструювання агента — хід і кроки, тригери, журнал запусків, стан, готові набори — це група /v1/dashboard/*. Вона не є публічним контрактом: нею користується сам кабінет, і вона змінюється разом з інтерфейсом. Користуватись нею можна, але сумісності між версіями ми тут не обіцяємо. Для глибокого обходу сайту вона не потрібна: POST /v1/admin/scrape з тілом {"url": "…", "max_pages": 50, "refresh_days": 7} — це публічна частина (max_pages понад 50 зрізається до 50; refresh_days — перечитувати раз на стільки днів, від 1 до 180; без поля розклад не ставиться).
Публічне й стабільне — рівно те, що перелічено вище: /v1/api/*, /v1/admin/*, вхідний вебхук тригера й вихідні вебхуки.
Далі
Вебхуки — події від нас до вас і сигнал від вас до агента.