API для разработчиков

REST API v1

Кратко

REST API v1 tuk-tuk.online для серверных интеграций: список каналов, карточки контактов, история сообщений, ссылки на медиа и отправка сообщений (текст, голосовые, медиа, email) в любой подключённый канал. Авторизация по API-ключу со scopes, ответы в JSON.

  • Базовый URL: https://back.tuk-tuk.online/api/v1. Ключ вида tuk_sk_... передаётся в заголовке Authorization: Bearer <ключ> или X-Api-Key: <ключ>.
  • Ключ создаётся в кабинете: Настройки проекта → вкладка API → «Создать ключ». Показывается один раз, хранится как SHA-256 хэш; можно задать scopes, срок действия, белый список IP и лимит запросов в минуту.
  • Scopes (22): messengers:read, contacts:read, contacts:write, messages:read, media:read, messages:send, files:write, funnels:read, funnels:write, stories:read, stories:write, broadcasts:read, broadcasts:write, chains:read, chains:write, assistants:read, assistants:write, tasks:read, tasks:write, webhooks:manage, account:read. Без нужного scope ответ 403.
  • Самоописание: GET /api/v1/manifest возвращает список ресурсов с признаком доступности для текущего ключа, GET /api/v1/openapi.json отдаёт спецификацию OpenAPI 3.1. Оба требуют только валидный ключ.
  • Отложенная отправка: POST /api/v1/messages/schedule с полем sendAt (ISO-8601, минимум на 30 секунд вперёд), список GET /api/v1/messages/scheduled, отмена DELETE /api/v1/messages/scheduled/:id.
  • Идемпотентность: заголовок Idempotency-Key на отправке и постановке в расписание; повтор возвращает первый результат, ключ живёт сутки.
  • Другие ресурсы: контакты на запись, файлы (POST /files забирает файл по ссылке), рассылки с расчётом аудитории, связки, воронки, ИИ-ассистенты с паузой в диалоге, задачи, подписки на события, состояние аккаунта.
  • Эндпоинты: GET /me, GET /messengers, GET /contacts/:id, GET /contacts?phone=|email=, GET /contacts/:id/messages (limit 1–100, по умолчанию 30, offset), GET /media/:fileId, POST /messages.
  • Формат ответа: успех { "data": ... } (у списков плюс { "meta": ... }), ошибка { "statusCode", "error", "message" }; у 429 тело { "error": { "code": "rate_limited", "message" } }.
  • Отправка POST /messages: адресат dialogId/contactId или channelId + phone/email/identifier; обязателен text или mediaUrl; mediaType: photo, voice, audio, video, document; для EMAIL subject и rawEmail.
  • Коды ошибок: 400 (нет text и mediaUrl), 403 (ключ или scope), 404 (не найдено в рабочем пространстве), 429 (лимит запросов ключа в минуту).
На этой странице

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": "..." } (нужен scope messages:send).
  • Чтобы отправить по номеру телефона или email без известного контакта, передай channelId и phone или email: контакт найдётся или создастся в этом канале.
  • Чтобы отправить позже, вызови POST /api/v1/messages/schedule с полем sendAt в ISO-8601: момент отправки держит платформа, ты можешь завершиться сразу.
  • Чтобы прочитать историю, вызови GET /api/v1/contacts/:id/messages?limit=30&offset=0 (scope messages:read); новые сообщения идут первыми.
  • Чтобы найти контакт, вызови GET /api/v1/contacts?phone=... или ?email=... (scope contacts:read); при отсутствии получишь 404. Без этих параметров тот же адрес отдаёт список с фильтрами.
  • При повторе запроса передавай заголовок Idempotency-Key: повтор вернёт первый результат, а не отправит дубль.
  • Ключ создаётся в кабинете: Настройки проекта → вкладка API → «Создать ключ». Ключ показывается один раз, формат tuk_sk_.... Проверить ключ: GET /api/v1/me.
  • Готовый MCP-сервер и порядок работы для агентов: Для нейросетей и MCP.

#Создать API-ключ

Вкладка «API» в настройках проекта
Ключи выпускаются во вкладке «API» настроек проекта. Секрет показывается один раз.
  1. Откройте Настройки проекта в личном кабинете.
  2. Перейдите на вкладку API.
  3. Нажмите Создать ключ, задайте название и выберите права (scopes).
  4. Скопируйте ключ сразу: он показывается один раз и хранится в зашифрованном виде. Потеряли: отзовите и создайте новый.

Для ключа можно задать срок действия, белый список IP и лимит запросов в минуту. В любой момент ключ можно отозвать или удалить.

#Авторизация

Создание API-ключа
  1. Название ключа.
  2. Права (scopes) и срок действия задаются здесь же; секрет показывается один раз.

Передавайте ключ в одном из заголовков:

HTTP
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.

JSON
// один объект
{ "data": { } }

// список
{ "data": [ ], "meta": { "total": 12 } }

// ошибка
{ "statusCode": 403, "error": "Forbidden", "message": "Описание ошибки" }

#Эндпоинты

#GET/api/v1/me

Данные ключа и рабочего пространства. Удобно проверить, что ключ работает. Scope не требуется.

Параметров нет.

Запрос

JavaScript
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);
PHP
$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"]);
Python
import requests
r = requests.get(
    "https://back.tuk-tuk.online/api/v1/me",
    headers={"Authorization": "Bearer tuk_sk_ВАШ_КЛЮЧ"},
)
print(r.json()["data"])

Ответ

JSON
{
  "data": {
    "keyName": "Интеграция с CRM",
    "scopes": ["messengers:read", "contacts:read", "messages:read", "messages:send"],
    "projectId": null
  }
}

Ошибки: 403 (нет ключа, неверный, отозван, истёк, IP не разрешён), 429 (лимит запросов).

#GET/api/v1/messengers

Все подключённые каналы. Секреты (токены ботов и т.п.) не возвращаются. Scope: messengers:read.

Параметров нет.

Запрос

JavaScript
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);
PHP
$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"]);
Python
import requests
r = requests.get(
    "https://back.tuk-tuk.online/api/v1/messengers",
    headers={"X-Api-Key": "tuk_sk_ВАШ_КЛЮЧ"},
)
print(r.json()["data"])

Ответ

JSON
{
  "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 контакта

Запрос

JavaScript
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);
PHP
$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"]);
Python
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"])

Ответ

JSON
{
  "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 контакта

Запрос

JavaScript
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);
PHP
$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"]);
Python
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.

JSON
{
  "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

Запрос

JavaScript
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);
PHP
$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"]);
Python
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"])

Ответ

JSON
{
  "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 файла

Запрос

JavaScript
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);
PHP
$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"];
Python
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"])

Ответ

JSON
{
  "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 / contactIdstringодин из способов адресацииID существующего контакта
channelIdstringда, при отправке по телефону, email или identifierКанал, через который уходит сообщение
phone / email / identifierstringодин из способов адресацииПолучатель: контакт ищется или создаётся в канале channelId
textstringда, если нет mediaUrlТекст сообщения
subjectstringнетТема письма, только для канала EMAIL
mediaUrlstringнетСсылка на вложение (картинка, голосовое, видео, документ)
mediaTypestringнетphoto, voice, audio, video, document
rawEmailbooleanнетEMAIL: true, отправить письмо как есть, без обёртки и футера с отпиской

Запрос

JavaScript
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);
PHP
$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"]);
Python
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).

По номеру телефона, контакт создастся при необходимости:

JSON
{ "channelId": "550e8400-...-099", "phone": "+79991234567", "text": "Код подтверждения: 1234" }

Голосовое сообщение:

JSON
{ "dialogId": "f1e2aaaa-...", "mediaUrl": "https://example.com/note.ogg", "mediaType": "voice" }

Email через канал EMAIL:

JSON
{ "channelId": "550e8400-...-0ee", "email": "ivan@example.com", "subject": "Ваш договор", "text": "Здравствуйте! Во вложении договор." }

Ответ (одинаковый по структуре для всех вариантов)

JSON
{
  "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Превышен лимит запросов ключа в минуту

Примеры тел ошибок:

JSON
// 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/schedulemessages:send
GET/messages/scheduledmessages:send
DELETE/messages/scheduled/:idmessages:send

Адресат указывается так же, как в обычной отправке. Дополнительно нужно поле sendAt в ISO-8601, минимум на 30 секунд вперёд.

Shell
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/contactscontacts:write
PATCH/contacts/:idcontacts:write
POST/contacts/:id/notescontacts:write

Фильтры списка: search, tag, channelId, status, hasPhone, hasEmail, archived, includeClosed, limit, offset. В PATCH можно передать tags и customFields целиком, сменить status, убрать диалог в архив и выставить chainsBlocked, чтобы связки не вмешивались в разговор.

#Файлы

МетодАдресПраво
GET/filesmedia:read
POST/filesfiles:write

POST /files с телом { "url": "https://..." } забирает файл по ссылке в хранилище рабочего пространства и возвращает постоянный адрес. Ограничение 50 МБ, дальше используйте загрузку файлом на POST /api/upload.

#Рассылки

МетодАдресПраво
GET POST/broadcastsbroadcasts:read / broadcasts:write
POST/broadcasts/previewbroadcasts:read
GET/broadcasts/audience/optionsbroadcasts:read
PATCH DELETE/broadcasts/:idbroadcasts:write
POST/broadcasts/:id/start, /pause, /resume, /cancel, /duplicate, /retry-failedbroadcasts:write
GET/broadcasts/:id/recipientsbroadcasts:read

Порядок такой: создать черновик, посчитать аудиторию через preview, запустить. Запуск пересобирает список получателей заново, поэтому он разрешён только для черновика и запланированной рассылки. Рассылку на паузе продолжают через resume, завершённую повторяют через duplicate с последующим запуском копии: иначе те, кому уже отправили, получат сообщение второй раз. Аудитория задаётся объектом audience: теги, статусы, каналы, активность за N дней либо явный список dialogIds. Темп задают delayMinSec и delayMaxSec, окно отправки, windowFromMin и windowToMin.

#Связки и воронки

МетодАдресПраво
GET/chains/block-typeschains:read
GET POST/chainschains:read / chains:write
GET PATCH DELETE/chains/:idпо действию
POST/chains/:id/toggle, /clonechains:write
GET POST/funnels и вложенныеfunnels:read / funnels:write
GET POST DELETE/messengers/:id/stories, /archive, /summary, /syncstories:read / stories:write

#ИИ-ассистенты

МетодАдресПраво
GET/assistants, /assistants/:idassistants:read
PATCH/assistants/:idassistants:write
POST/assistants/:id/toggleassistants:write
POST/assistants/pause-dialogassistants:write
DELETE/assistants/pause-dialog/:dialogIdassistants:write

#Задачи

GET POST /tasks, GET PATCH DELETE /tasks/:id. Права tasks:read и tasks:write. Поля: title, description, status, priority, dialogId, assigneeId, dueDate.

#Подписки на события

МетодАдресПраво
GET/events/typeswebhooks:manage
GET POST/events/subscriptionswebhooks:manage
GET PATCH DELETE/events/subscriptions/:idwebhooks:manage
POST/events/subscriptions/:id/rotate-secretwebhooks:manage
GET/events/subscriptions/:id/deliverieswebhooks:manage

Секрет подписи возвращается только при создании и ротации. Проверка подписи и список событий: Event Webhooks.

#Состояние аккаунта

GET /account с правом account:read возвращает баланс, тариф, срок подписки, лимиты хранилища и расход сообщений. Поле canSend со значением false означает, что отправка не пройдёт, причина в blockedReason.

#Самоописание API

МетодАдресЧто отдаёт
GET/manifestСписок ресурсов, требуемые права, признак доступности для текущего ключа, соглашения и ссылки
GET/openapi.jsonСпецификация OpenAPI 3.1

Оба вызова требуют валидный ключ, но не требуют дополнительных прав. Это первое, что стоит вызвать внешней системе: дальше не нужно угадывать, что доступно.

#Идемпотентность

Отправка и постановка в расписание принимают заголовок Idempotency-Key. Повторный запрос с тем же значением вернёт результат первого, а не отправит второе сообщение. Это защита от ретрая при обрыве связи. Ключ живёт сутки.

HTTP
POST /api/v1/messages
Authorization: Bearer tuk_sk_...
Idempotency-Key: order-4821-confirm

#Безопасность

  • Ключ хранится только в виде SHA-256 хэша. Восстановить его нельзя, поэтому копируйте сразу при создании.
  • Ключ привязан к одному рабочему пространству и видит только его данные.
  • Ключ можно ограничить по правам (scopes), сроку действия, IP и лимиту запросов в минуту.
  • Отозванный ключ перестаёт работать немедленно.

Уведомления о событиях в обратную сторону (новое сообщение, смена статуса диалога) приходят через Event Webhooks.