Публічний API
Публічний API Aelo — це API аналітики дзвінків (call analytics API, conversation intelligence API): ви надсилаєте записи дзвінків або чатів із ваших власних систем — CRM, платформи телефонії, кастомного пайплайна — і забираєте записи та їх аналіз (оцінки, резюме, заперечення) після завершення обробки. API прив’язаний до організації: кожен запит діє від імені організації, яка видала ключ, і кожна відповідь обмежена даними цієї організації.
Доступний на тарифах Starter і вище. Організації на безкоштовному тарифі не можуть ні видавати, ні використовувати публічні API-ключі.
Отримання ключа
Section titled “Отримання ключа”- Перейдіть у Налаштування → API ключі. Цей розділ бачить лише власник
організації (роль
client) — адміністратори, супервайзери й агенти не можуть керувати ключами. - Оберіть назву, позначте один або обидва скоупи (
records:write,records:read) і за потреби вкажіть дату завершення дії. - Ключ у відкритому вигляді (
aelo_sk_…) показується один раз, у момент створення. Збережіть його самостійно — Aelo зберігає лише його хеш і не зможе показати його повторно. Якщо ключ втрачено, відкличте його і видайте новий.
Організація може мати не більше 10 активних ключів одночасно — відкликайте невикористані, перш ніж видавати нові.
Автентифікація
Section titled “Автентифікація”Кожен запит передає ключ як bearer-токен:
Authorization: Bearer aelo_sk_YOUR_KEYУсі ендпоінти знаходяться під https://api.aelo.cloud/api/public/v1.
Ключ відкриває доступ лише до того, що дозволяють його скоупи:
| Скоуп | Дає доступ до |
|---|---|
records:write | Створення записів (POST /records, POST /records/upload) |
records:read | Список і читання записів та аналізів (три маршрути GET) |
Запит до ендпоінта, який не покривають скоупи ключа, завершиться помилкою
insufficient_scope, навіть якщо сам ключ дійсний.
Ліміти
Section titled “Ліміти”| Ліміт | Значення |
|---|---|
| Запитів на ключ | 200 / хвилину |
Розмір multipart-завантаження (POST /records/upload) | 25 МБ |
Розмір файлу за fileUrl (POST /records) | 100 МБ, або 25 МБ, якщо джерело не повідомляє Content-Length |
Тайм-аут завантаження за fileUrl | 30 секунд |
| Активних API-ключів на організацію | 10 |
| Розмір сторінки списку записів | 50 за замовчуванням, максимум 100 (limit понад 100 мовчки зменшується, а не відхиляється) |
Ліміт для multipart нижчий за ліміт для fileUrl, бо multipart-тіло потрібно
повністю буферизувати в пам’яті перш ніж Aelo зможе його прочитати, а
завантаження за fileUrl йде потоком напряму у сховище — за умови, що джерело
повідомляє свій Content-Length. Джерело, яке його не повідомляє, потоком
передати не можна: воно буферизується в пам’яті, як multipart-тіло, і обмежене
тими самими 25 МБ. Якщо ваш аудіофайл
більший за 25 МБ, завантажте його у сховище, до якого маєте доступ, і
передайте fileUrl замість самого файлу — обидва варіанти детально розібрані
у Завантаженні дзвінків і чатів.
Ендпоінти
Section titled “Ендпоінти”| Метод і шлях | Скоуп | Що робить |
|---|---|---|
POST /records | records:write | Створює запис із fileUrl (дзвінки) або textContent (чати) |
POST /records/upload | records:write | Створює запис дзвінка із завантаженого аудіофайлу (multipart) |
GET /records | records:read | Список записів вашої організації |
GET /records/{recordId} | records:read | Отримати один запис |
GET /records/{recordId}/analysis | records:read | Отримати останній аналіз запису |
Обидва ендпоінти завантаження, їхні поля запиту, поведінка ідемпотентності та попередження, які вони повертають, розібрані у Завантаженні дзвінків і чатів. Решта описана нижче.
GET /records
Section titled “GET /records”Повертає записи від найновіших до найстаріших. Архівні записи виключені — і
ніяк не позначені: у відповіді немає поля archived, тож архівний запис
просто не з’являється у списку.
Параметри запиту:
| Параметр | За замовчуванням | Примітка |
|---|---|---|
limit | 50 | Обмежений зверху значенням 100 |
offset | 0 | |
createdAfter | — | ISO-8601. Включно (createdAt >= createdAfter) |
createdBefore | — | ISO-8601. Включно (createdAt <= createdBefore) |
{ "data": [ { "id": "rec_...", "projectId": "your-project-id", "type": "call", "status": "completed", "externalId": "crm-call-12345", "createdAt": "2026-07-01T10:00:00.000Z", "occurredAt": "2026-07-01T09:58:12.000Z", "durationSeconds": 184, "agentId": "42", "agentName": "Ivan Petrov", "callDirection": "outbound" } ], "pagination": { "limit": 50, "offset": 0, "total": 1 }}GET /records/{recordId}
Section titled “GET /records/{recordId}”Повертає один запис у тому самому форматі, що й список. Відповідає
record_not_found (404), якщо id не існує або належить іншій організації —
ці два випадки навмисно невідрізнювані.
GET /records/{recordId}/analysis
Section titled “GET /records/{recordId}/analysis”Повертає останній аналіз запису.
{ "recordId": "rec_...", "analysisId": "an_...", "createdAt": "2026-07-01T10:04:30.000Z", "summary": "Customer asked about pricing tiers; agent...", "qualityScore": 78, "metrics": { "greetingScore": 90, "needsScore": 70, "clarityScore": 80, "objectionScore": 65, "closingScore": 75, "politenessScore": 95, "saleProbability": 62 }}qualityScore — це канонічна оцінка: те саме число, що показує ваш
дашборд для цього дзвінка, а не самооцінка моделі. Кожна метрика дорівнює
null, якщо аналіз не дав по ній значення (безоцінна категорія дзвінка або
пункт рубрики, вимкнений у вашому проєкті) — ніколи не 0 замість «не
оцінено». saleProbability стосується лише дзвінків; для чатів воно завжди
null.
Відповідь навмисно вужча за те, що Aelo зберігає всередині: провайдер, модель, профіль промпту, кількість токенів і вартість не входять у публічний контракт.
Дві ситуації, що виглядають як 404, розрізняються кодом помилки, бо подальша дія відрізняється:
record_not_found— не існує сам id запису (або він не ваш). Виправте id.analysis_not_found— запис існує, але аналізу в нього немає.details.analysisExpectedкаже, чи він ще буде:true— продовжуйте опитувати,false— запис завершився без аналізу і ніколи його не матиме, опитування час припинити. Частина дзвінків закінчується так за задумом: надто короткий для оцінювання дзвінок (details.reason: "short_call") або запис, що впав у пайплайні ("record_failed").details.recordStatusу будь-якому разі повідомляє поточний статус запису.
Помилки
Section titled “Помилки”Будь-яка помилка повертається в одному форматі:
{ "error": { "code": "invalid_request", "message": "Human-readable description.", "details": { "field": "..." } }}details необов’язкове і, якщо присутнє, описує лише ваш власний запит —
ніколи внутрішній стан. Нерозпізнане поле в JSON-тілі, формі чи рядку запиту
відповідає invalid_request і називає кожне проблемне поле, а також підказку
didYouMean, якщо знайдено близький збіг зі справжнім ім’ям (наприклад,
projectID → projectId).
| Код | Статус | Значення |
|---|---|---|
invalid_api_key | 401 | Відсутній/некоректний заголовок Authorization, або ключ невідомий, відкликаний чи прострочений (усі три випадки виглядають однаково — навмисно) |
insufficient_scope | 403 | У ключа немає скоупу, потрібного цьому ендпоінту |
tier_not_eligible | 403 | Організація на безкоштовному тарифі |
feature_disabled | 403 | Адміністратор вашої організації вимкнув публічний API. Ключ залишається дійсним, зміна тарифу не допоможе — попросіть увімкнути назад |
insufficient_balance | 402 | Включені в тариф хвилини за цей цикл вичерпані, а баланс кредитів порожній. Запис не створено — поповніть баланс у «Налаштування → Білінг» і надішліть запит ще раз |
project_not_found | 404 | projectId не існує або належить іншій організації |
project_not_accepting_records | 409 | Проєкт існує, але його статус paused або archived — адміністратор організації має знову активувати його, перш ніж проєкт зможе приймати записи |
record_not_found | 404 | Id запису не існує або належить іншій організації |
analysis_not_found | 404 | Запис існує, але аналізу немає — опитуйте, поки details.analysisExpected = true, і припиніть, коли false |
not_found | 404 | Такого маршруту під /api/public/v1 не існує |
rate_limited | 429 | Понад 200 запитів за хвилину на цей ключ |
payload_too_large | 413 | Див. Ліміти вище |
unsupported_media_type | 415 | Завантажений/скачаний контент — не аудіо і не відео |
invalid_request | 400 | Тіло запиту, форма або рядок запиту не пройшли валідацію |
fetch_failed | 400 | Не вдалося скачати файл за fileUrl |
resolution_unavailable | 503 | Aelo зараз не змогла перевірити адресу призначення fileUrl — тимчасово, повторіть (заголовок Retry-After) |
service_unavailable | 503 | Сховище аналізів тимчасово недоступне — тимчасово, повторіть (заголовок Retry-After) |
internal_error | 500 | Непередбачений збій на боці сервера |
Відповідь 503 завжди містить заголовок Retry-After (у секундах) — не
вважайте це остаточною відмовою, повторіть запит через цей час.
Aelo — це API аналітики дзвінків?
Section titled “Aelo — це API аналітики дзвінків?”Так. Публічний API Aelo — REST API аналітики дзвінків (call analytics API) на
https://api.aelo.cloud/api/public/v1: Bearer-ключі організації (aelo_sk_…),
скоупи records:write / records:read, 200 запитів на хвилину на ключ.
Доступний на тарифах Starter і вище.
Як завантажити записи дзвінків на аналіз?
Section titled “Як завантажити записи дзвінків на аналіз?”Два способи: POST /records/upload приймає сам аудіофайл (multipart, до
25 МБ); POST /records приймає fileUrl, звідки Aelo завантажить запис (до
100 МБ). Чати надсилаються через POST /records як textContent. Повторні
надсилання дедуплікуються за externalId: передайте свій ідентифікатор, і
повторний запит поверне вихідний запис, а не створить другий. Обидва ендпоінти
описані в розділі Завантаження дзвінків і чатів.
Чи працює API з Bitrix24?
Section titled “Чи працює API з Bitrix24?”Bitrix24 він зазвичай не потрібен: нативна інтеграція аналізує дзвінки взагалі без коду. Публічний API — для всього іншого: власної телефонії, дата-пайплайна або CRM, з якою в Aelo поки немає інтеграції.
Дивіться також
Section titled “Дивіться також”- Завантаження дзвінків і чатів — поля запиту, ліміти розміру, ідемпотентність і попередження для обох ендпоінтів завантаження
- Ціни — публічний API входить у тарифи Starter і вище