Перейти к содержимому

Публикация поста

Публикация асинхронная: вы создаёте публикацию, Warmup ставит её в очередь и публикует в каждую выбранную соцсеть, а вы опрашиваете результат.

Соцсеть text photo story Лимит текста
Facebook да да да 63 206
Instagram — да да 2 200
Threads да да — 500

Одна публикация уходит в 1–3 соцсети. Каждая соцсеть из списка должна поддерживать выбранный kind.

  1. Загрузите картинку (для kind: text не нужно). До 15 МБ; Warmup конвертирует её в JPEG.

    Окно терминала
    curl -X POST https://api.warmup.social/projects/$PROJECT_ID/media \
    -H "Authorization: Bearer $WARMUP_TOKEN" \
    -F "file=@photo.jpg"
    { "id": "6f1c…", "url": "https://…", "width": 1080, "height": 1350 }

    Для ленты Instagram пропорции должны быть от 4:5 (вертикаль) до 1.91:1 (горизонталь). Для сторис лучше всего 9:16.

  2. Создайте публикацию.

    Окно терминала
    curl -X POST https://api.warmup.social/projects/$PROJECT_ID/publications \
    -H "Authorization: Bearer $WARMUP_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{
    "kind": "photo",
    "platforms": ["instagram", "threads"],
    "text": "Новая коллекция уже в продаже",
    "mediaId": "6f1c…"
    }'

    API отвечает 202 Accepted: публикация и по цели на каждую соцсеть в статусе queued.

  3. Опрашивайте, пока все цели не завершатся.

    Окно терминала
    curl https://api.warmup.social/projects/$PROJECT_ID/publications/$PUBLICATION_ID \
    -H "Authorization: Bearer $WARMUP_TOKEN"

    Каждая цель проходит queued → publishing → published или failed. Опрашивайте раз в несколько секунд; обычно всё завершается в пределах минуты.

const api = "https://api.warmup.social";
const headers = { Authorization: `Bearer ${process.env.WARMUP_TOKEN}` };
async function waitForPublication(projectId, publicationId) {
for (let attempt = 0; attempt < 40; attempt++) {
const res = await fetch(`${api}/projects/${projectId}/publications/${publicationId}`, { headers });
const publication = await res.json();
if (publication.targets.every((t) => t.status === "published" || t.status === "failed")) {
return publication;
}
await new Promise((resolve) => setTimeout(resolve, 3000));
}
throw new Error("Публикация ещё не завершилась");
}

У цели в статусе published есть permalink (ссылка на пост), externalPostId и publishedAt. У цели в статусе failed есть errorCode:

errorCode Что делать
needs_reauth, connection_not_ready Переподключить соцсеть (руководство).
media_rejected Соцсеть отклонила картинку — проверьте размер и пропорции.
media_aspect_ratio Картинка не подходит для ленты Instagram.
rate_limit Сработал лимит публикаций самой соцсети — повторите позже.
meta_unavailable Meta временно недоступна — повторите позже.
published_unconfirmed Meta опубликовала пост, но не вернула его id. Скорее всего, пост вышел — проверьте аккаунт перед повтором.

Публикация — это план: state по умолчанию scheduled, и без scheduledAt она уходит сразу. Передайте будущий scheduledAt (ISO 8601 со смещением) — и публикация уйдёт в этот момент, с точностью около полуминуты. timezone — IANA-пояс, в котором вы ввели время: Warmup хранит его, чтобы показывать пост в планере в правильном локальном времени.

{
"kind": "photo",
"platforms": ["instagram"],
"mediaId": "6f1c…",
"text": "Пятничный дроп",
"scheduledAt": "2026-11-06T18:00:00+02:00",
"timezone": "Europe/Kyiv"
}
  • state: draft оставляет публикацию в планере без отправки. Черновику не нужны подключённые соцсети, у него может не быть даты.
  • Пока публикация не отправлена (state — draft или scheduled), PATCH /projects/{id}/publications/{publicationId} меняет любое поле; scheduledAt: null снимает дату, state: scheduled без даты отправляет сразу. После отправки PATCH отвечает 409 publication_dispatched.
  • POST /projects/{id}/publications/{publicationId}/publish отправляет черновик или запланированную публикацию немедленно.
  • DELETE /projects/{id}/publications/{publicationId} убирает публикацию из планера; та, что ещё queued, отменяется.
  • GET /projects/{id}/publications?from=…&to=… возвращает окно планера плюс все черновики без даты; state сводит результат по соцсетям (publishing, published, failed).
  • Для kind: text нужен text; для photo и story нужен mediaId, а для text он запрещён.
  • Соцсети из platforms должны быть подключены и в статусе active, иначе API ответит 409 с connection_missing или connection_not_ready.
  • Загрузка и создание публикаций делят лимит 30 запросов в минуту на пользователя (сверх него — 429).
  • GET /projects/{id}/publications без from/to возвращает 50 последних публикаций.