Com-Poster
Справка

API и вебхуки

API нужен, когда посты готовит другая система — сайт, CRM, интернет-магазин, n8n, Make или AI-агент — а Com-Poster публикует их по расписанию в Telegram, VK, MAX и Одноклассники. Приём постов по API и вебхуки доступны с тарифа Start.

1. Получите API-ключ и ID каналов

  • API-ключ — вкладка API-ключи → «Создать API-ключ». Полное значение показывается один раз — сохраните его. Ключ привязан к проекту: посты, отправленные с ним, попадут в этот проект.
  • ID канала (social_account_id) — на вкладке Каналы под названием каждого канала; клик копирует его.

Ключ передаётся в заголовке Authorization: Bearer <ключ>. Если ключ утёк — отзовите его на той же вкладке и выпустите новый.

2. Создайте пост

curl -X POST https://com-poster.ru/api/v1/posts \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "targets": [
      { "social_account_id": "ID_КАНАЛА_1" },
      { "social_account_id": "ID_КАНАЛА_2" }
    ],
    "caption": "Текст поста. **Жирный** и _курсив_ поддерживаются там, где их понимает площадка.",
    "media": [
      { "url": "https://example.com/photo.jpg", "mime_type": "image/jpeg" }
    ],
    "scheduled_at": "2026-11-01T09:00:00Z"
  }'
  • targets — один или несколько каналов проекта, можно на разных площадках.
  • caption — текст до 4096 символов. Учитывайте лимиты площадок: в Telegram с картинкой — 1024, в MAX — 4000. Поддерживается разметка **жирный**, _курсив_, [текст](ссылка); для VK и ОК она убирается автоматически.
  • media — до 10 файлов, можно пустой массив. Либо публичная ссылка с mime_type, либо upload_id загруженного файла (см. ниже).
  • scheduled_at — время в UTC в формате ISO 8601 с Z на конце. Время в прошлом — публикация сразу.

Ответ 201 — созданный пост с id и списком targets: у каждого канала свой статус. Пост сразу появляется в календаре проекта, его можно поправить или перенести вручную.

3. Загрузка файла (если нет публичной ссылки)

curl -X POST https://com-poster.ru/api/v1/media \
  -H "Authorization: Bearer $API_KEY" \
  -F "file=@photo.jpg;type=image/jpeg"

# ответ: { "id": "UPLOAD_ID", "url": "...", "mimeType": "image/jpeg", ... }
# дальше в посте: "media": [{ "upload_id": "UPLOAD_ID" }]

Фото — до 50 МБ. Видео — по лимитам тарифа (с Studio). Один upload_id можно прикрепить только к одному посту.

4. Узнайте результат: вебхуки

Укажите адрес в Настройках проекта → Вебхуки (доступно владельцу проекта). Когда пост опубликуется или окончательно не сможет выйти в каком-то канале, Com-Poster отправит на этот адрес POST:

{
  "event": "post_target.published",
  "project_id": "...",
  "post_id": "...",
  "post_target_id": "...",
  "social_account_id": "...",
  "platform": "TELEGRAM",
  "status": "PUBLISHED",
  "external_post_id": "123",
  "error_message": null,
  "occurred_at": "2026-11-01T09:00:03.000Z"
}

event — post_target.published или post_target.failed, на каждый канал отдельно. В заголовке X-Composter-Signature — HMAC-SHA256 от тела запроса, ключ — «Секрет подписи» из тех же настроек. Проверяйте подпись, чтобы отличать настоящие вебхуки от поддельных:

// Node.js / Express: проверка подписи вебхука
import crypto from 'node:crypto';

app.post('/hooks/com-poster', express.raw({ type: 'application/json' }), (req, res) => {
  const expected = crypto
    .createHmac('sha256', process.env.COMPOSTER_WEBHOOK_SECRET)
    .update(req.body) // сырое тело запроса, до JSON.parse
    .digest('hex');
  const got = req.get('X-Composter-Signature') ?? '';
  if (got.length !== expected.length ||
      !crypto.timingSafeEqual(Buffer.from(got), Buffer.from(expected))) {
    return res.sendStatus(401);
  }
  const event = JSON.parse(req.body.toString('utf8'));
  // event.status: PUBLISHED или FAILED
  res.sendStatus(200);
});

n8n, Make и другие no-code сервисы

Используйте обычный HTTP-запрос: в n8n — узел HTTP Request, в Make — модуль HTTP → Make a request. Метод POST, адрес https://com-poster.ru/api/v1/posts, заголовок Authorization со значением Bearer ваш_ключ, тело — JSON как в примере выше. Для вебхуков о статусе в n8n подойдёт узел Webhook.

Ошибки

ОтветЧто значит
401 unauthorizedКлюч неверный, отозван или не передан.
400 invalid_inputТело запроса не по формату — подробности в поле details.
400 unknown_social_accountКанала с таким ID нет в проекте этого ключа.
400 validation_failedПост не проходит ограничения площадки (длина текста, число вложений) — текст причины в ответе.
400 unknown_upload_id / upload_already_attachedФайла с таким upload_id нет или он уже прикреплён к другому посту.
402 plan_limit_reachedИсчерпан лимит тарифа (например, постов в месяц).
403 plan_feature_unavailableAPI недоступен на текущем тарифе.
429Больше 60 запросов в минуту — повторите позже.

Если пост принят, но не вышел, причина придёт в вебхуке (error_message) и будет видна в календаре. Расшифровка частых ошибок площадок — здесь.