Перейти к основному содержимому
Опубликовано: 

Sendsay API — Руководство по работе

Полная документация Sendsay API

Общие сведения​

Sendsay API — это HTTP-интерфейс для управления рассылками, подписчиками, статистикой и другими объектами системы. Взаимодействие с API происходит через JSON-запросы, которые отправляются методом POST.

Параметры подключения​

  • Транспорт: HTTPS (HTTP 1.0/1.1)
  • Шифрование: TLS 1.2 или TLS 1.3
  • Адрес API: https://api.sendsay.ru

Рекомендуется использовать расширение SNI.

Имя api.sendsay.ru имеет несколько IP-адресов. Если соединение с одним из них не устанавливается, рекомендуется повторить запрос с использованием другого.

Важно

Для работы с API в CDP поддерживается ГОСТ-шифрование. Это дополнительная услуга. Чтобы подключить её, .

Формат запроса​

Endpoint​

POST https://api.sendsay.ru/general/api/v100/json/account

Где account — код вашего аккаунта (совпадает с основным логином).

Для вызовов, не требующих привязки к аккаунту (например, ping), используйте символ -:

POST https://api.sendsay.ru/general/api/v100/json/-

Тело запроса​

Основные требования к телу запроса:

  • Content-Type: application/json.
  • Кодировка: UTF-8.
  • Максимальный размер: 400 Мбайт.

Запрос — это JSON-объект с обязательным полем action:

{
"action": "название_действия",
"session": "идентификатор_сессии",
"параметр1": "значение1",
"параметр2": "значение2"
}
Важно

Используйте готовые функции вашего языка программирования для сериализации JSON. «Красивое» форматирование пробелами необязательно — его отсутствие уменьшает размер запроса и ускоряет обработку.

Аутентификация​

Важно

Для автоматической работы по API создавайте отдельный саблогин с максимально ограниченными правами и используйте для него API-ключ или JWT-токен.

Как создать саблогин

Sendsay API поддерживает несколько способов аутентификации. Ниже подробно описан рекомендуемый для автоматизации способ — API-ключ. Остальные способы смотрите в документации API.

API-ключ (рекомендуется для автоматизации)​

Создайте API-ключ заранее вызовом sys.user.apikey.create.

Аутентификация действует на один вызов и не требует logout. Процессы, запущенные асинхронными вызовами, продолжат работу до завершения.

В теле запроса:

{
"action": "нужное_действие",
"apikey": "ваш_ключ_api",
"...": "..."
}

В HTTP-заголовке:

Authorization: sendsay apikey=ключ-api-url-кодированный

Как получить API-ключ

Другие способы аутентификации​

СпособОписаниеДокументация
Логин и пароль (сессия)Классическая аутентификация через login / logout. Сессия живёт несколько часовПодробнее
JWT-токенАутентификация по подписанному токену (RFC 7519). Подходит для серверного взаимодействияПодробнее
Двухфакторная аутентификация (SMS)Логин + пароль с подтверждением кодом из SMSПодробнее
OpenIDАутентификация через внешний OpenID-провайдер. Для настройки Подробнее

Формат ответа​

Ответ — JSON в кодировке UTF-8 (Content-Type: application/json).

HTTP-статусы​

СтатусЗначение
200Нормальный ответ
3xxПеренаправления (необходимо обрабатывать)
503Превышение лимита запросов (rate_limit)
ПрочиеНеизвестная ошибка — повторите запрос

Общие поля ответа​

Каждый ответ может содержать следующие служебные поля:

{
"request.id": "значение из запроса",
"duration": "время обработки в секундах",
"_ehid": "служебная строка для отладки"
}

Успешный ответ​

{
"request.id": "...",
"поле_результата_1": "значение",
"поле_результата_2": "значение"
}

Ответ с ошибкой​

При ошибке в ответе появляется массив errors:

{
"errors": [
{
"id": "код_ошибки",
"explain": "описание ошибки"
}
]
}
Важно

Поле explain может быть строкой, массивом или объектом — в зависимости от вызова и ошибки.

Некоторые вызовы также возвращают массив warnings — это события, которые помешали выполнить вызов частично, но не делают его ошибочным.

Специальный случай: требуется смена пароля​

Если вы получили ошибку error/auth/failed с уточнением force_change_password, для продолжения работы необходимо:

  1. Сменить пароль через вызов sys.user.set с разовой аутентификацией.
  2. Повторить исходный запрос (он не был выполнен). Может потребоваться новая сессия.

Синхронные и асинхронные запросы​

Синхронные запросы​

По умолчанию запросы синхронны — запрошенное действие выполняется (или не выполняется при ошибке) к моменту ответа. Результат содержится непосредственно в ответе.

Асинхронные запросы​

Асинхронный запросы означает, что действие принято в очередь, и будет выполнено позже. В ответе возвращается track.id — номер трекера для отслеживания статуса запроса через track.get.

Примеры асинхронных запросов: issue.send, member.import, stat.uni, member.list и другие.

Отслеживание асинхронных запросов​

Получение состояния запроса​

{
"action": "track.get",
"id": 12345
}

Ответ содержит поле obj с подробной информацией: статус, дата создания, параметры запроса, прогресс выполнения (ETA) и результаты.

Основные статусы трекера​

КодЗначение
-7Приостановлен
-6Не прошёл модерацию
-5На премодерации
-4Отложенное действие
-3Отменён
-2Завершился с ошибкой
-1Завершился успешно
0Принят
1Запущен
2Начата обработка
3–6Промежуточные этапы (сортировка, форматирование, генерация отчёта, антиспам)

Список всех трекеров​

{
"action": "track.list",
"filter": [],
"order": [],
"skip": 0,
"first": 50
}

Информация о запросах старше двух месяцев удаляется автоматически. Для issue.send/personal — через два дня.

Отмена и пауза​

Для трекеров в состояниях 0, 1 или 2 можно установить статус «отменён» (-3) или «пауза» (-7, только для member.import):

{
"action": "track.set",
"id": 12345,
"status": -3
}
Важно

Уже совершённые действия останутся в силе. Отмена прекращает обработку только оставшейся части списка действий.

Лимиты и ограничения​

ПараметрЗначение
Одновременных запросов на изменение данных5
Одновременных запросов всего10
Запросов в секунду80
Максимальный размер запроса400 Мбайт

При превышении лимитов вы получите ошибку rate_limit с HTTP-кодом 503.

Идентификация запросов (request.id)​

Необязательный параметр request.id помогает при отладке и обращениях в службу поддержки. Он возвращается в ответе без изменений.

Способы передачи​

В URL:

https://api.sendsay.ru/general/api/v100/json/account?request.id=мой-запрос-123

В теле запроса:

{
"action": "...",
"request.id": "мой-запрос-123"
}

В HTTP-заголовке:

X-Request-ID: мой-запрос-123
Важно

Нельзя указывать request.id несколькими способами одновременно — это вызовет ошибку double_request.id.

Защита от дублирования​

Для некоторых вызовов повторный запрос с тем же request.id в течение 15 минут вернёт ошибку repeated_request.id. Это правило действует для следующих вызовов:

  • issue.send
  • issue.send.multi
  • member.import
  • member.import.probe
  • member.sendconfirm

Время защиты можно увеличить (до 2 часов) через параметр repeated_request_ttl (в секундах).

Пакетные запросы — batch​

Пакетные запросы позволяют отправить несколько запросов за один вызов:

{
"action": "batch",
"stop_on_error": 0,
"do": [
{ "action": "первый_запрос", "...": "..." },
{ "action": "второй_запрос", "...": "..." }
]
}

Ответ:

{
"result": [
{"ответ на первый запрос"},
{"ответ на второй запрос"}
]
}

Особенности пакетных запросов:

  • Запросы выполняются последовательно.
  • Запросы изолированы друг от друга (результат одного недоступен в другом).
  • Порядок ответов совпадает с порядком запросов.
  • stop_on_error: 1 — прекращает выполнение после первой ошибки.
  • Аутентификация (session, one_time_auth) работает только в основном запросе.
  • login и logout во вложенных запросах вызовут ошибку.
  • Несколько статистических запросов в одном batch могут привести к ошибке нехватки памяти.

Кэширование ответов​

Кэширование ответов поддерживается для вызовов stat.uni и member.list.count и применяется только к успешным ответам.

Параметры кэша​

{
"action": "stat.uni",
"cache": {
"mode": "use",
"key": "мой-ключ-кэша",
"ttl": 3600
},
"...": "..."
}

Режимы кэширования​

РежимПоведение
ignoreНе использовать кэш
useВернуть из кэша, если есть; иначе вычислить и сохранить
refreshВычислить заново и сохранить в кэш
fetchВернуть из кэша, если есть; иначе — пустой ответ (без вычисления)

Правила для ключа кэша: до 64 печатных символов ASCII (без пробела). Ключи не пересекаются между разными вызовами, но видны всем саблогинам одного аккаунта.

Ответ с кэшем содержит поле cache:

{
"cache": {
"hit": 1,
"created": "2025-01-15 12:30:00",
"expired": "2025-01-15 13:30:00"
}
}
  • hit: 1 — данные из кэша,
  • hit: 0 — вычислены заново или кэш пуст.
Важно

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

Возвращаемое значение и способы получения результата​

Некоторые вызовы поддерживают параметр result, позволяющий указать, как использовать результат.

Вернуть в ответе (по умолчанию)​

Результат возвращается синхронно. Подходит для интерактивных интерфейсов (для автоматизации лучше использовать асинхронную схему).

{ "type": "response" }

Сохранить в Отчёты​

Файл хранится 90 дней. Формат: CSV, XLSX, HTML или JSON.

{ "type": "save", "to": "имя_файла", "format": "csv" }

Отправить на электронную почту​

Файл с результатом будет отправлен на указанную электронную почту.

{ "type": "email_file", "to": ["test@test.com"], "format": "xlsx", "filename": "отчёт.xlsx" }

Загрузить на внешний сервер (HTTP/HTTPS)​

Файл с результатом будет загружен на внешний сервер с указанным адресом.

{
"type": "url_file",
"to": "https://test.com/upload",
"name": "file",
"filename": "data.csv",
"format": "csv"
}

Загрузить по FTP/FTPS​

{
"type": "url_file",
"to": "ftp://ftp.test.com/reports/",
"filename": "data.csv",
"format": "csv"
}

Уведомление на почту (без самого результата)​

На указанную электронную почту поступит уведомление о готовности результата.

{ "type": "email_notify", "to": ["test@test.com"] }

Уведомление по SMS​

Уведомление о готовности результата придёт в виде SMS.

{ "type": "sms", "to": ["+79001234567"] }

Уведомление по внешней ссылке (GET)​

{ "type": "url_notify", "to": "https://test.com/callback" }

Не возвращать результат​

{ "type": "none" }

Параметры формата​

Для всех вариантов с format доступны дополнительные настройки:

  • compress — zip, bzip2, gzip или пусто (без сжатия).
  • separator — разделитель полей для CSV (по умолчанию запятая).
  • always_quote — 0 или 1 — всегда обрамлять значения кавычками в CSV.
  • utf8 — 0 или 1 — использовать UTF-8 для CSV (рекомендуется 1).
  • append — 0 или 1 — дописать в существующий файл (только без сжатия).
Важно

Кодировка по умолчанию для CSV зависит от даты создания аккаунта: до 28 февраля 2018 — windows-1251, после — UTF-8.

Представление данных​

Числа​

Числовые значения могут передаваться и возвращаться как JSON-число или как JSON-строка:

{"count": 123}
{"count": "123"}

Допустимо использовать оба варианта.

Даты​

В полях с датами указывается московское время. Формат поля:

YYYY-MM-DD hh:mm:ss

Можно указывать дату и время без лидирующих нулей, например: 2025-5-3 9:7:4.

Точность указывается метками: Ys (от года до секунды), Yh (до часа), YD (до дня).

Необязательные параметры​

  • Параметры логики работы: если отсутствуют или пусты — считаются как 0 (нет).
  • Текстовые параметры: если отсутствуют — считаются пустой строкой.

Порядок обработки вызовов​

Последовательность обработки параллельных вызовов не гарантируется. Если результат одного вызова зависит от другого, между ними лучше дождаться завершения первого вызова.

Если несколько вызовов изменяют один и тот же объект, их также лучше выполнять последовательно — параллельные изменения могут привести к некорректному результату.

При удалении связанных объектов сначала удаляется основной объект, а после подтверждения операции — связанные с ним объекты.

Защищённые сущности​

Большинство сущностей поддерживают защиту от изменения и удаления через свойство protected:

ЗначениеОписание
0Не защищено (по умолчанию)
1Защищено пользователем
-1Защищено системой

Для изменения или удаления объекта с protected = 1 передайте параметр ignore_protection со значением, равным id объекта.

Какие сущности можно защитить: списки и сегменты, черновики, форматы, анкеты, формы, логины, роли, действия по расписанию, триггеры, DKIM-ключи, адреса email-отправителей, названия SMS-отправителей.

Логины и пароли в ссылках​

Некоторые вызовы обращаются к внешним серверам по HTTP(S) или FTP(S). Учётные данные можно указать прямо в URL:

http://login:password@host.tld/path

Однако рекомендуется использовать объект «Внешняя аутентификация», созданный через authext.create, и указывать его номер:

http://authext:777@host.tld/path

В этом случае логин и пароль хранятся в объекте внешней аутентификации и не отображаются в запросе, поэтому они не будут видны в ссылке.

Проверка доступности​

Пинг без аутентификации​

{ "action": "ping" }

Ответ:

{ "pong": "случайное_значение" }

Пинг с аутентификацией​

{ "action": "pong" }

Ответ:

{
"ping": "случайное_значение",
"account": "код_аккаунта",
"sublogin": "код_саблогина",
"via": "способ_аутентификации"
}

Готовые библиотеки​

Готовые библиотеки для работы с Sendsay API доступны на GitHub.

Читайте также:
Отправка массовых рассылок через Sendsay API
Отправка транзакционных рассылок через Sendsay API
Импорт и добавление контактов через Sendsay API
Получение статистики через Sendsay API