Посібник з інтеграції для корпоративних клієнтів — з прикладами, які можна скопіювати й запустити.
Базова адреса всіх запитів:
https://treka.eu/api/v1.
Кожен приклад нижче — робочий curl; підставте свій токен і виконайте.
Токен видає Treka.eu (менеджер або адмін-панель). Додавайте його в заголовок
Authorization кожного запиту. Токен несе скоупи:
leads:read, leads:write,
trips:read, trips:write,
webhooks:read. Якщо токену бракує потрібного скоупу — відповідь 403.
# Перевірте токен: хто ви, які скоупи й ліміти curl https://treka.eu/api/v1/me \ -H "Authorization: Bearer <ВАШ_ТОКЕН>"
{
"id": 12,
"name": "Ваша компанія",
"status": "active",
"sees_all_leads": false,
"rate_limit_per_min": 120,
"abilities": ["leads:read", "leads:write"],
"webhook": { "configured": true, "url": "https://ваш-сервер/трека-хук" }
}
Найпростіший спосіб віддати заявку: надішліть сирий текст — так, як його написав би пасажир чи диспетчер. Той самий класифікатор, що читає стрічку спільнот, сам вичитає маршрут, дату, кількість пасажирів і телефон. Нічого структурувати наперед не треба.
POST/messages — скоуп leads:write
curl -X POST https://treka.eu/api/v1/messages \ -H "Authorization: Bearer <ВАШ_ТОКЕН>" \ -H "Content-Type: application/json" \ -d '{ "text": "Треба з Києва до Варшави 20 липня, 3 людини, +380631112233", "author_name": "Олена" }'
Розпізнавання йде асинхронно, тож відповідь одразу — 202 Accepted зі статусом pending:
{
"data": {
"id": 84213,
"status": "pending",
"text": "Треба з Києва до Варшави 20 липня, 3 людини, +380631112233",
"author_name": "Олена",
"leads": [],
"created_at": "2026-07-20T09:14:02+00:00"
}
}
lead.created (або lead.matched, якщо заявка
збіглася з вашим зареєстрованим маршрутом) — див. розділ 6. Якщо вебхуків не налаштовано —
опитайте статус (нижче).
Скоуп leads:read. Опитуйте, доки status не стане relevant (є leads) або irrelevant (у тексті заявки немає).
curl https://treka.eu/api/v1/messages/84213 \
-H "Authorization: Bearer <ВАШ_ТОКЕН>"
{
"data": {
"id": 84213,
"status": "relevant",
"leads": [
{
"id": 550141,
"direction": "ua_pl",
"from": { "city": "Київ", "key": "kyiv" },
"to": { "city": "Варшава", "key": "warsaw" },
"travel_date": "2026-07-20",
"passengers": 3,
"phone": "+380631112233"
}
]
}
}
Поля from_key, to_key та
cities приймають канонічний ключ міста з газетира —
kyiv, berlin, warsaw.
Ключі не завжди вгадуються (частина латиницею, а частина кирилицею чи поштовим індексом), тож не
вигадуйте їх — знайдіть у довіднику.
GET/cities — будь-який валідний токен, скоуп не потрібен
# Резолвимо назву в точний ключ — точний збіг повертається першим curl "https://treka.eu/api/v1/cities?q=Львів" \ -H "Authorization: Bearer <ВАШ_ТОКЕН>"
{
"data": [
{ "key": "lviv", "name": "Львів",
"country": { "code": "ua", "name": "Україна" } }
],
"meta": { "total": 1, "per_page": 50, "current_page": 1 }
}
| Параметр | Опис |
|---|---|
q | Пошук за назвою або ключем; також резолвить довільний текст у ключ (q=Львів). |
country | Фільтр за ISO-кодом країни (ua, de, pl). |
per_page / page | Пагінація (макс. 200 на сторінку). |
POST /messages (розділ 2) читає місто з
тексту сам — там ключі не потрібні взагалі.
Якщо ви вже маєте розібрані поля й хочете синхронну відповідь із готовим лідом —
надсилайте POST /leads. Міста — це канонічні ключі газетира
(kyiv, berlin…), телефон обовʼязковий.
POST/leads — скоуп leads:write
curl -X POST https://treka.eu/api/v1/leads \ -H "Authorization: Bearer <ВАШ_ТОКЕН>" \ -H "Content-Type: application/json" \ -d '{ "from_key": "kyiv", "to_key": "berlin", "travel_date": "2026-07-20", "passengers": 2, "phone": "+380631112233", "comment": "Дві валізи, заберіть від дому" }'
Відповідь — 201 Created з готовим лідом у полі data.
GET/leads — скоуп leads:read.
За замовчуванням повертає ліди, що збігаються з вашими маршрутами. Фільтри —
через query-параметри.
curl "https://treka.eu/api/v1/leads?direction=ua_pl&date_from=2026-07-18&per_page=50" \ -H "Authorization: Bearer <ВАШ_ТОКЕН>"
| Параметр | Опис |
|---|---|
scope | mine (типово) або all — весь фід (потрібен контракт sees_all_leads). |
direction | Напрямок, напр. ua_de, ua_pl. |
from / to | Канонічні ключі міст. |
country | ISO-код країни на будь-якому кінці напрямку. |
date_from / date_to | Діапазон дати поїздки (Y-m-d). |
per_page / page | Пагінація (макс. 100 на сторінку). |
Щоб фід і вебхуки lead.matched звужувалися до ваших коридорів —
зареєструйте маршрути. Напрямок виводиться з міст автоматично.
POST/trips — скоуп trips:write
curl -X POST https://treka.eu/api/v1/trips \ -H "Authorization: Bearer <ВАШ_ТОКЕН>" \ -H "Content-Type: application/json" \ -d '{ "cities": ["kyiv", "warsaw"], "pickup_radius_km": 100 }'
Керування: GET /trips, PATCH /trips/{id}, DELETE /trips/{id}.
Коли заявку розпізнано, Treka.eu робить POST на ваш
webhook_url з подією lead.created або
lead.matched. URL і секрет налаштовує адмін-панель Treka.eu; поточну
конфігурацію видно через GET /webhooks.
{
"event": "lead.matched",
"occurred_at": "2026-07-20T09:14:05+00:00",
"data": { /* той самий обʼєкт лід, що й у GET /leads */ }
}
Кожен запит несе заголовки X-Treka-Event,
X-Treka-Timestamp і X-Treka-Signature.
Перед обробкою перевірте підпис:
// PHP $raw = file_get_contents('php://input'); $expected = 'sha256=' . hash_hmac( 'sha256', $_SERVER['HTTP_X_TREKA_TIMESTAMP'] . '.' . $raw, $webhookSecret, ); if (! hash_equals($expected, $_SERVER['HTTP_X_TREKA_SIGNATURE'])) { http_response_code(403); exit; } // підпис валідний — обробляйте, і відповідайте 2xx для підтвердження
// Node.js
const crypto = require('crypto');
const expected = 'sha256=' + crypto
.createHmac('sha256', webhookSecret)
.update(req.headers['x-treka-timestamp'] + '.' + rawBody)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers['x-treka-signature']))) {
return res.sendStatus(403);
}
Відповідайте 2xx, щоб підтвердити доставку. Невдалі доставки повторюються з наростаючою затримкою; лог — GET /webhooks/deliveries.
| HTTP | Коли |
|---|---|
200 | Успіх (читання, оновлення, видалення). |
201 | Створено (структурований лід POST /leads, маршрут POST /trips). |
202 | Заявку у довільній формі прийнято, розпізнавання триває. |
Будь-яка помилка — єдиний конверт зі стабільним кодом code.
Гілкуйтеся у коді саме по ньому, а не по тексту message (він українською й може
змінюватися). Поле errors є лише для validation_failed.
{
"code": "scope_missing",
"message": "Токену бракує потрібного скоупу."
}
# приклад validation_failed { "code": "validation_failed", "message": "Перевірте поля запиту.", "errors": { "text": ["The text field is required."] } }
| code | HTTP | Значення |
|---|---|---|
unauthenticated | 401 | Токен відсутній або недійсний. |
invalid_token | 403 | Токен не належить партнерському акаунту. |
access_suspended | 403 | Партнерський доступ призупинено. |
scope_missing | 403 | Токену бракує потрібного скоупу (ability). |
plan_restricted | 403 | Дію не включено у ваш тариф (напр. `scope=all`). |
forbidden | 403 | Доступ заборонено. |
not_found | 404 | Ресурс не існує або не належить вам. |
method_not_allowed | 405 | HTTP-метод не підтримується для цього ресурсу. |
validation_failed | 422 | Помилка валідації; деталі полів — у `errors`. |
route_limit_reached | 422 | Досягнуто ліміту активних маршрутів тарифу. |
rate_limited | 429 | Перевищено ліміт запитів (`rate_limit_per_min`). |
server_error | 500 | Внутрішня помилка сервера. |