API и вебхуки
Как присылать посты в Com-Poster из своей системы, CRM, n8n или Make: 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_unavailable | API недоступен на текущем тарифе. |
429 | Больше 60 запросов в минуту — повторите позже. |
Если пост принят, но не вышел, причина придёт в вебхуке (error_message) и будет видна в календаре. Расшифровка частых ошибок площадок — здесь.