REST API v1 даёт вашему серверу прямой доступ к платформе: список каналов, карточки контактов, история переписки, медиа-файлы и отправка сообщений в любой подключённый мессенджер. Авторизация по API-ключу, ответы в JSON.
Базовый URL: https://back.tuk-tuk.online/api/v1. Успешные ответы обёрнуты в { "data": ... }, у списков добавляется { "meta": ... }.
#Для ИИ-агента
- Начни с
GET /api/v1/manifest: он вернёт список ресурсов и покажет, что разрешено именно твоему ключу. Полная спецификация:GET /api/v1/openapi.json. - Чтобы отправить сообщение, вызови
POST /api/v1/messagesс заголовкомAuthorization: Bearer tuk_sk_...и телом{ "dialogId": "...", "text": "..." }(нужен scopemessages:send). - Чтобы отправить по номеру телефона или email без известного контакта, передай
channelIdиphoneилиemail: контакт найдётся или создастся в этом канале. - Чтобы отправить позже, вызови
POST /api/v1/messages/scheduleс полемsendAtв ISO-8601: момент отправки держит платформа, ты можешь завершиться сразу. - Чтобы прочитать историю, вызови
GET /api/v1/contacts/:id/messages?limit=30&offset=0(scopemessages:read); новые сообщения идут первыми. - Чтобы найти контакт, вызови
GET /api/v1/contacts?phone=...или?email=...(scopecontacts:read); при отсутствии получишь404. Без этих параметров тот же адрес отдаёт список с фильтрами. - При повторе запроса передавай заголовок
Idempotency-Key: повтор вернёт первый результат, а не отправит дубль. - Ключ создаётся в кабинете: Настройки проекта → вкладка API → «Создать ключ». Ключ показывается один раз, формат
tuk_sk_.... Проверить ключ:GET /api/v1/me. - Готовый MCP-сервер и порядок работы для агентов: Для нейросетей и MCP.
#Создать API-ключ

- Откройте Настройки проекта в личном кабинете.
- Перейдите на вкладку API.
- Нажмите Создать ключ, задайте название и выберите права (scopes).
- Скопируйте ключ сразу: он показывается один раз и хранится в зашифрованном виде. Потеряли: отзовите и создайте новый.
Для ключа можно задать срок действия, белый список IP и лимит запросов в минуту. В любой момент ключ можно отозвать или удалить.
#Авторизация

- Название ключа.
- Права (scopes) и срок действия задаются здесь же; секрет показывается один раз.
Передавайте ключ в одном из заголовков:
Authorization: Bearer tuk_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
X-Api-Key: tuk_sk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxУ каждого метода ниже примеры на JavaScript, PHP и Python, переключайте вкладки.
#Права (scopes)
У ключа есть набор прав, каждый метод требует своё:
| Scope | Право |
|---|---|
messengers:read | Список привязанных мессенджеров |
contacts:read | Чтение карточек контактов |
contacts:write | Создание и изменение контактов, теги, поля, статусы, заметки |
messages:read | Чтение истории сообщений |
media:read | Ссылки на медиа и список файлов |
messages:send | Отправка сообщений, включая отложенные |
files:write | Загрузка файлов в хранилище |
funnels:read | Чтение воронок автопостинга |
funnels:write | Сборка и запуск воронок |
stories:read | Истории Telegram-аккаунта: эфир, архив, просмотры и реакции |
stories:write | Публикация и удаление историй, принудительный замер |
broadcasts:read | Рассылки и отчёты доставки |
broadcasts:write | Создание, запуск и остановка рассылок |
chains:read | Чтение связок автоматизации |
chains:write | Создание и изменение связок |
assistants:read | Чтение ИИ-ассистентов |
assistants:write | Настройка ассистентов и пауза в диалоге |
tasks:read | Чтение задач |
tasks:write | Создание и изменение задач |
webhooks:manage | Подписки на события платформы |
account:read | Баланс, тариф, лимиты, расход |
Если у ключа нет нужного права, ответ 403 с указанием недостающего scope.
#Формат ответа
Все ответы в JSON. Полезные данные всегда в поле data. У списков дополнительно приходит объект meta (счётчики и пагинация). Ошибки возвращаются с кодом 4xx/5xx и телом с полями statusCode, error, message.
// один объект
{ "data": { } }
// список
{ "data": [ ], "meta": { "total": 12 } }
// ошибка
{ "statusCode": 403, "error": "Forbidden", "message": "Описание ошибки" }#Эндпоинты
#GET/api/v1/me
Данные ключа и рабочего пространства. Удобно проверить, что ключ работает. Scope не требуется.
Параметров нет.
Запрос
const res = await fetch("https://back.tuk-tuk.online/api/v1/me", {
headers: { "Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ" },
});
const json = await res.json();
console.log(json.data);$ch = curl_init("https://back.tuk-tuk.online/api/v1/me");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer tuk_sk_ВАШ_КЛЮЧ"],
]);
$json = json_decode(curl_exec($ch), true);
print_r($json["data"]);import requests
r = requests.get(
"https://back.tuk-tuk.online/api/v1/me",
headers={"Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ"},
)
print(r.json()["data"])Ответ
{
"data": {
"keyName": "Интеграция с CRM",
"scopes": ["messengers:read", "contacts:read", "messages:read", "messages:send"],
"projectId": null
}
}Ошибки: 403 (нет ключа, неверный, отозван, истёк, IP не разрешён), 429 (лимит запросов).
#GET/api/v1/messengers
Все подключённые каналы. Секреты (токены ботов и т.п.) не возвращаются. Scope: messengers:read.
Параметров нет.
Запрос
const res = await fetch("https://back.tuk-tuk.online/api/v1/messengers", {
headers: { "X-Api-Key": "tuk_sk_ВАШ_КЛЮЧ" },
});
const { data } = await res.json();
console.log(data);$ch = curl_init("https://back.tuk-tuk.online/api/v1/messengers");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["X-Api-Key: tuk_sk_ВАШ_КЛЮЧ"],
]);
$json = json_decode(curl_exec($ch), true);
print_r($json["data"]);import requests
r = requests.get(
"https://back.tuk-tuk.online/api/v1/messengers",
headers={"X-Api-Key": "tuk_sk_ВАШ_КЛЮЧ"},
)
print(r.json()["data"])Ответ
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440001",
"type": "TELEGRAM_BOT",
"name": "Бот поддержки",
"botName": "@my_support_bot",
"isActive": true,
"status": "connected",
"error": null,
"errorAt": null,
"createdAt": "2026-01-12T09:30:00.000Z",
"updatedAt": "2026-05-20T15:45:00.000Z"
},
{
"id": "550e8400-e29b-41d4-a716-446655440002",
"type": "EMAIL",
"name": "Почта поддержки",
"botName": null,
"isActive": false,
"status": "disabled",
"error": null,
"errorAt": null,
"createdAt": "2026-02-01T10:00:00.000Z",
"updatedAt": "2026-05-10T08:15:00.000Z"
}
],
"meta": { "total": 2 }
}Поле status: connected (подключён), error (активен, но есть ошибка), disabled (выключен).
Ошибки: 403 (нет scope messengers:read или проблема с ключом), 429.
#GET/api/v1/contacts/:id
Карточка контакта по его ID. Scope: contacts:read.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
id (в пути) | string | да | ID контакта |
Запрос
const id = "f1e2aaaa-1111-2222-3333-444455556666";
const res = await fetch("https://back.tuk-tuk.online/api/v1/contacts/" + id, {
headers: { "Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ" },
});
console.log((await res.json()).data);$id = "f1e2aaaa-1111-2222-3333-444455556666";
$ch = curl_init("https://back.tuk-tuk.online/api/v1/contacts/$id");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer tuk_sk_ВАШ_КЛЮЧ"],
]);
$json = json_decode(curl_exec($ch), true);
print_r($json["data"]);import requests
contact_id = "f1e2aaaa-1111-2222-3333-444455556666"
r = requests.get(
f"https://back.tuk-tuk.online/api/v1/contacts/{contact_id}",
headers={"Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ"},
)
print(r.json()["data"])Ответ
{
"data": {
"id": "f1e2aaaa-1111-2222-3333-444455556666",
"name": "Иван Петров",
"identifier": "123456789",
"phone": "+79991234567",
"email": "ivan@example.com",
"avatarUrl": "https://back.tuk-tuk.online/uploads/avatars/abc.jpg",
"channelId": "550e8400-e29b-41d4-a716-446655440001",
"channelType": "TELEGRAM_BOT",
"source": "Telegram",
"tags": ["vip", "оплатил"],
"customFields": { "Город": "Москва" },
"dialogStatus": "IN_PROGRESS",
"archivedAt": null,
"unreadCount": 0,
"lastMessageAt": "2026-05-28T10:00:00.000Z",
"createdAt": "2026-01-12T09:30:00.000Z",
"updatedAt": "2026-05-28T10:00:00.000Z"
}
}Ошибки: 403 (нет scope contacts:read), 404 (контакт не найден в этом рабочем пространстве), 429.
#GET/api/v1/contacts
Поиск контакта по телефону или email. Возвращает ту же карточку, что и запрос по ID, либо 404, если контакт не найден. Scope: contacts:read.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
phone (query) | string | одно из двух | Телефон контакта |
email (query) | string | одно из двух | Email контакта |
Запрос
const phone = encodeURIComponent("+79991234567");
const res = await fetch("https://back.tuk-tuk.online/api/v1/contacts?phone=" + phone, {
headers: { "Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ" },
});
console.log((await res.json()).data);$phone = urlencode("+79991234567");
$ch = curl_init("https://back.tuk-tuk.online/api/v1/contacts?phone=$phone");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer tuk_sk_ВАШ_КЛЮЧ"],
]);
$json = json_decode(curl_exec($ch), true);
print_r($json["data"]);import requests
r = requests.get(
"https://back.tuk-tuk.online/api/v1/contacts",
params={"phone": "+79991234567"},
headers={"Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ"},
)
print(r.json()["data"])Ответ
Карточка контакта в поле data, структура как у GET /api/v1/contacts/:id.
{
"data": {
"id": "f1e2aaaa-1111-2222-3333-444455556666",
"name": "Иван Петров",
"phone": "+79991234567",
"email": "ivan@example.com",
"channelId": "550e8400-e29b-41d4-a716-446655440001",
"channelType": "TELEGRAM_BOT",
"dialogStatus": "IN_PROGRESS"
}
}Ошибки: 403 (нет scope contacts:read), 404 (контакт не найден), 429.
#GET/api/v1/contacts/:id/messages
История переписки с контактом, новые сообщения сверху. Scope: messages:read.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
id (в пути) | string | да | ID контакта |
limit (query) | number | нет | Сколько сообщений вернуть, 1–100, по умолчанию 30 |
offset (query) | number | нет | Смещение для пагинации, по умолчанию 0 |
Запрос
const id = "f1e2aaaa-1111-2222-3333-444455556666";
const res = await fetch("https://back.tuk-tuk.online/api/v1/contacts/" + id + "/messages?limit=2", {
headers: { "Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ" },
});
const { data, meta } = await res.json();
console.log(data, meta);$id = "f1e2aaaa-1111-2222-3333-444455556666";
$ch = curl_init("https://back.tuk-tuk.online/api/v1/contacts/$id/messages?limit=2");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer tuk_sk_ВАШ_КЛЮЧ"],
]);
$json = json_decode(curl_exec($ch), true);
print_r($json["data"]);import requests
contact_id = "f1e2aaaa-1111-2222-3333-444455556666"
r = requests.get(
f"https://back.tuk-tuk.online/api/v1/contacts/{contact_id}/messages",
params={"limit": 2},
headers={"Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ"},
)
print(r.json()["data"])Ответ
{
"data": [
{
"id": "9c0f-msg-2",
"direction": "OUTBOUND",
"body": "Здравствуйте! Чем можем помочь?",
"channelId": "550e8400-e29b-41d4-a716-446655440001",
"channelType": "TELEGRAM_BOT",
"mediaUrl": null,
"mediaType": null,
"downloadUrl": null,
"transcription": null,
"messageStatus": "SENT",
"externalMessageId": "12346",
"senderName": null,
"createdAt": "2026-05-28T10:01:00.000Z"
},
{
"id": "9c0f-msg-1",
"direction": "INBOUND",
"body": "",
"channelId": "550e8400-e29b-41d4-a716-446655440001",
"channelType": "TELEGRAM_BOT",
"mediaUrl": "https://back.tuk-tuk.online/uploads/voice/xyz.ogg",
"mediaType": "voice",
"downloadUrl": "https://back.tuk-tuk.online/uploads/voice/xyz.ogg",
"transcription": "Здравствуйте, есть вопрос по заказу",
"messageStatus": null,
"externalMessageId": "12345",
"senderName": null,
"createdAt": "2026-05-28T10:00:00.000Z"
}
],
"meta": { "total": 142, "hasMore": true, "limit": 2, "offset": 0 }
}Поле direction: INBOUND (от клиента), OUTBOUND (клиенту), SYSTEM, NOTE. У медиа-сообщений есть готовая ссылка downloadUrl для скачивания. Пагинация: meta.hasMore говорит, есть ли ещё сообщения за пределами limit + offset.
Ошибки: 403 (нет scope messages:read), 404 (контакт не найден), 429.
#GET/api/v1/media/:fileId
Метаданные файла и ссылка на скачивание. Scope: media:read.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
fileId (в пути) | string | да | ID файла |
Запрос
const fileId = "file-uuid-1234";
const res = await fetch("https://back.tuk-tuk.online/api/v1/media/" + fileId, {
headers: { "Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ" },
});
const { data } = await res.json();
console.log(data.downloadUrl);$fileId = "file-uuid-1234";
$ch = curl_init("https://back.tuk-tuk.online/api/v1/media/$fileId");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Authorization: Bearer tuk_sk_ВАШ_КЛЮЧ"],
]);
$json = json_decode(curl_exec($ch), true);
echo $json["data"]["downloadUrl"];import requests
file_id = "file-uuid-1234"
r = requests.get(
f"https://back.tuk-tuk.online/api/v1/media/{file_id}",
headers={"Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ"},
)
print(r.json()["data"]["downloadUrl"])Ответ
{
"data": {
"id": "file-uuid-1234",
"originalName": "photo.jpg",
"mimeType": "image/jpeg",
"size": 184320,
"url": "https://back.tuk-tuk.online/uploads/2026/05/abc.jpg",
"downloadUrl": "https://back.tuk-tuk.online/uploads/2026/05/abc.jpg",
"dialogId": "f1e2aaaa-1111-2222-3333-444455556666",
"createdAt": "2026-05-28T10:00:00.000Z"
}
}Ошибки: 403 (нет scope media:read), 404 (файл не найден), 429.
#POST/api/v1/messages
Отправка текста, голосового, медиа или email. Scope: messages:send. Получателя задают одним из двух способов:
dialogIdилиcontactId: в существующий диалог (контакт);channelId+phone,emailилиidentifier: найти или создать контакт в указанном канале.
| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
dialogId / contactId | string | один из способов адресации | ID существующего контакта |
channelId | string | да, при отправке по телефону, email или identifier | Канал, через который уходит сообщение |
phone / email / identifier | string | один из способов адресации | Получатель: контакт ищется или создаётся в канале channelId |
text | string | да, если нет mediaUrl | Текст сообщения |
subject | string | нет | Тема письма, только для канала EMAIL |
mediaUrl | string | нет | Ссылка на вложение (картинка, голосовое, видео, документ) |
mediaType | string | нет | photo, voice, audio, video, document |
rawEmail | boolean | нет | EMAIL: true, отправить письмо как есть, без обёртки и футера с отпиской |
Запрос
const res = await fetch("https://back.tuk-tuk.online/api/v1/messages", {
method: "POST",
headers: {
"Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ",
"Content-Type": "application/json",
},
body: JSON.stringify({
dialogId: "f1e2aaaa-1111-2222-3333-444455556666",
text: "Ваш заказ готов к выдаче!",
}),
});
console.log((await res.json()).data);$ch = curl_init("https://back.tuk-tuk.online/api/v1/messages");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer tuk_sk_ВАШ_КЛЮЧ",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"dialogId" => "f1e2aaaa-1111-2222-3333-444455556666",
"text" => "Ваш заказ готов к выдаче!",
]),
]);
$json = json_decode(curl_exec($ch), true);
print_r($json["data"]);import requests
r = requests.post(
"https://back.tuk-tuk.online/api/v1/messages",
headers={"Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ"},
json={
"dialogId": "f1e2aaaa-1111-2222-3333-444455556666",
"text": "Ваш заказ готов к выдаче!",
},
)
print(r.json()["data"])Другие варианты тела (меняется только JSON).
По номеру телефона, контакт создастся при необходимости:
{ "channelId": "550e8400-...-099", "phone": "+79991234567", "text": "Код подтверждения: 1234" }Голосовое сообщение:
{ "dialogId": "f1e2aaaa-...", "mediaUrl": "https://example.com/note.ogg", "mediaType": "voice" }Email через канал EMAIL:
{ "channelId": "550e8400-...-0ee", "email": "ivan@example.com", "subject": "Ваш договор", "text": "Здравствуйте! Во вложении договор." }Ответ (одинаковый по структуре для всех вариантов)
{
"data": {
"id": "a1b2-new-msg",
"dialogId": "f1e2aaaa-1111-2222-3333-444455556666",
"direction": "OUTBOUND",
"body": "Ваш заказ готов к выдаче!",
"mediaUrl": null,
"mediaType": null,
"messageStatus": "SENT",
"externalMessageId": "67890",
"createdAt": "2026-05-29T12:00:00.000Z"
}
}Поле messageStatus: SENT (отправлено), FAILED (доставка не удалась). Отправка списывается с баланса так же, как ответ оператора, и идёт через тот же канал, что и в личном кабинете.
Ошибки: 400 (нет ни text, ни mediaUrl), 403 (нет scope messages:send), 404 (контакт не найден), 429.
#Коды ошибок
Ошибки приходят с HTTP-кодом и телом вида { "statusCode": ..., "error": ..., "message": ... }.
| Код | Когда возникает |
|---|---|
400 | Некорректный запрос (например, нет ни text, ни mediaUrl) |
403 | Нет ключа, неверный, отозван, истёк, IP не разрешён, не хватает scope |
404 | Ресурс не найден в этом рабочем пространстве |
429 | Превышен лимит запросов ключа в минуту |
Примеры тел ошибок:
// 403: не хватает прав ключа
{
"statusCode": 403,
"error": "Forbidden",
"message": "Недостаточно прав ключа. Требуется scope: messages:send"
}
// 404: контакт не найден
{ "statusCode": 404, "error": "Not Found", "message": "Контакт не найден" }
// 429: превышен лимит запросов
{ "error": { "code": "rate_limited", "message": "Превышен лимит запросов (120/мин) для этого API-ключа" } }#Остальные разделы API
Кроме контактов, истории и отправки, ключ открывает ещё восемь ресурсов. Ниже краткая карта; полный список всех 96 адресов с правами лежит в справочнике эндпоинтов, схемы запросов отдаёт GET /api/v1/openapi.json.
#Отложенная отправка
| Метод | Адрес | Право |
|---|---|---|
| POST | /messages/schedule | messages:send |
| GET | /messages/scheduled | messages:send |
| DELETE | /messages/scheduled/:id | messages:send |
Адресат указывается так же, как в обычной отправке. Дополнительно нужно поле sendAt в ISO-8601, минимум на 30 секунд вперёд.
curl -X POST https://back.tuk-tuk.online/api/v1/messages/schedule -H "Authorization: Bearer $TUK_KEY" -H "Content-Type: application/json" -d '{"dialogId":"f1e2...","text":"Напоминаю о встрече","sendAt":"2026-09-10T06:00:00Z"}'#Контакты на запись
| Метод | Адрес | Право |
|---|---|---|
| GET | /contacts со списком фильтров | contacts:read |
| POST | /contacts | contacts:write |
| PATCH | /contacts/:id | contacts:write |
| POST | /contacts/:id/notes | contacts:write |
Фильтры списка: search, tag, channelId, status, hasPhone, hasEmail, archived, includeClosed, limit, offset. В PATCH можно передать tags и customFields целиком, сменить status, убрать диалог в архив и выставить chainsBlocked, чтобы связки не вмешивались в разговор.
#Файлы
| Метод | Адрес | Право |
|---|---|---|
| GET | /files | media:read |
| POST | /files | files:write |
POST /files с телом { "url": "https://..." } забирает файл по ссылке в хранилище рабочего пространства и возвращает постоянный адрес. Ограничение 50 МБ, дальше используйте загрузку файлом на POST /api/upload.
#Рассылки
| Метод | Адрес | Право |
|---|---|---|
| GET POST | /broadcasts | broadcasts:read / broadcasts:write |
| POST | /broadcasts/preview | broadcasts:read |
| GET | /broadcasts/audience/options | broadcasts:read |
| PATCH DELETE | /broadcasts/:id | broadcasts:write |
| POST | /broadcasts/:id/start, /pause, /resume, /cancel, /duplicate, /retry-failed | broadcasts:write |
| GET | /broadcasts/:id/recipients | broadcasts:read |
Порядок такой: создать черновик, посчитать аудиторию через preview, запустить. Запуск пересобирает список получателей заново, поэтому он разрешён только для черновика и запланированной рассылки. Рассылку на паузе продолжают через resume, завершённую повторяют через duplicate с последующим запуском копии: иначе те, кому уже отправили, получат сообщение второй раз. Аудитория задаётся объектом audience: теги, статусы, каналы, активность за N дней либо явный список dialogIds. Темп задают delayMinSec и delayMaxSec, окно отправки, windowFromMin и windowToMin.
#Связки и воронки
| Метод | Адрес | Право |
|---|---|---|
| GET | /chains/block-types | chains:read |
| GET POST | /chains | chains:read / chains:write |
| GET PATCH DELETE | /chains/:id | по действию |
| POST | /chains/:id/toggle, /clone | chains:write |
| GET POST | /funnels и вложенные | funnels:read / funnels:write |
| GET POST DELETE | /messengers/:id/stories, /archive, /summary, /sync | stories:read / stories:write |
#ИИ-ассистенты
| Метод | Адрес | Право |
|---|---|---|
| GET | /assistants, /assistants/:id | assistants:read |
| PATCH | /assistants/:id | assistants:write |
| POST | /assistants/:id/toggle | assistants:write |
| POST | /assistants/pause-dialog | assistants:write |
| DELETE | /assistants/pause-dialog/:dialogId | assistants:write |
#Задачи
GET POST /tasks, GET PATCH DELETE /tasks/:id. Права tasks:read и tasks:write. Поля: title, description, status, priority, dialogId, assigneeId, dueDate.
#Подписки на события
| Метод | Адрес | Право |
|---|---|---|
| GET | /events/types | webhooks:manage |
| GET POST | /events/subscriptions | webhooks:manage |
| GET PATCH DELETE | /events/subscriptions/:id | webhooks:manage |
| POST | /events/subscriptions/:id/rotate-secret | webhooks:manage |
| GET | /events/subscriptions/:id/deliveries | webhooks:manage |
Секрет подписи возвращается только при создании и ротации. Проверка подписи и список событий: Event Webhooks.
#Состояние аккаунта
GET /account с правом account:read возвращает баланс, тариф, срок подписки, лимиты хранилища и расход сообщений. Поле canSend со значением false означает, что отправка не пройдёт, причина в blockedReason.
#Самоописание API
| Метод | Адрес | Что отдаёт |
|---|---|---|
| GET | /manifest | Список ресурсов, требуемые права, признак доступности для текущего ключа, соглашения и ссылки |
| GET | /openapi.json | Спецификация OpenAPI 3.1 |
Оба вызова требуют валидный ключ, но не требуют дополнительных прав. Это первое, что стоит вызвать внешней системе: дальше не нужно угадывать, что доступно.
#Идемпотентность
Отправка и постановка в расписание принимают заголовок Idempotency-Key. Повторный запрос с тем же значением вернёт результат первого, а не отправит второе сообщение. Это защита от ретрая при обрыве связи. Ключ живёт сутки.
POST /api/v1/messages
Authorization: Bearer tuk_sk_...
Idempotency-Key: order-4821-confirm#Безопасность
- Ключ хранится только в виде SHA-256 хэша. Восстановить его нельзя, поэтому копируйте сразу при создании.
- Ключ привязан к одному рабочему пространству и видит только его данные.
- Ключ можно ограничить по правам (scopes), сроку действия, IP и лимиту запросов в минуту.
- Отозванный ключ перестаёт работать немедленно.
Уведомления о событиях в обратную сторону (новое сообщение, смена статуса диалога) приходят через Event Webhooks.
