Към съдържанието

Ръководство за разработчици

Изпращайте публикации към Amaposta от собствения си поток за съдържание: качете медийни файлове, създайте публикация за всеки канал, насрочете я и получете известие, когато излезе.

Удостоверяване

Създайте API ключ в таблото от Настройки, API и уебхукове. Ключовете започват с ss_live_, принадлежат на едно работно пространство и могат да се ограничат до определени проекти. Изпращайте ключа като bearer токен във всяка заявка:

Проверка на ключ
curl https://www.amaposta.com/api/v1/me \
  -H "Authorization: Bearer ss_live_…"

Отговорът посочва ключа, правата му и работното пространство. Всеки ключ има едно или повече права:

ОбхватПозволява
content:readЧетене на проекти, канали, публикации и медийни файлове.
content:writeКачване на медийни файлове и създаване или редактиране на публикации.
posts:publishНасрочване и публикуване без преглед. Без това право публикациите отиват във входящата кутия за преглед в проекти с одобрения и остават чернови навсякъде другаде.

Всеки ключ може да прави 120 заявки в минута. Над това получавате 429 с код rate_limited; изчакайте малко и опитайте отново.

Проекти и канали

Публикациите принадлежат на проект. Избройте проектите, видими за ключа ви, после каналите в един от тях. Ще ви трябва идентификаторът на канал, за да го посочите като цел или да замените текста му.

Изброяване на проекти и канали
curl https://www.amaposta.com/api/v1/projects \
  -H "Authorization: Bearer $AMAPOSTA_KEY"

curl https://www.amaposta.com/api/v1/projects/$PROJECT_ID/channels \
  -H "Authorization: Bearer $AMAPOSTA_KEY"

Каналът има provider (youtube, instagram, tiktok, x, facebook, custom или sandbox), status (active, expiring, needs_reconnect, error или disabled) и поддържани видове публикации в supports.

Качване на медийни файлове

Изображенията и видеоклиповете се качват веднъж за проект и могат да се използват в неограничен брой публикации. Има три начина за добавяне.

Директно качване

Изпратете файла като multipart form data в поле с име file. Най-подходящо за файлове до няколкостотин MB.

POST /api/v1/projects/{project_id}/media
curl https://www.amaposta.com/api/v1/projects/$PROJECT_ID/media \
  -H "Authorization: Bearer $AMAPOSTA_KEY" \
  -F "[email protected]"

Предварително подписано качване за големи файлове

Поискайте URL адрес за качване, изпратете байтовете директно в хранилището с PUT и уведомете Amaposta, че сте готови.

Три заявки
# 1. Ask for an upload URL. The response is {"media": { … }, "upload_url": "…"}
curl https://www.amaposta.com/api/v1/projects/$PROJECT_ID/media/uploads \
  -H "Authorization: Bearer $AMAPOSTA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filename": "batch-142.mp4", "content_type": "video/mp4", "size_bytes": 48213844}'

# 2. Upload the bytes to upload_url
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: video/mp4" \
  --upload-file batch-142.mp4

# 3. Finish the upload
curl -X POST https://www.amaposta.com/api/v1/media/$MEDIA_ID/complete \
  -H "Authorization: Bearer $AMAPOSTA_KEY"

Импортиране от URL адрес

Дайте на Amaposta публичен URL адрес и тя ще изтегли файла във фонов режим. Можете и да пропуснете тази стъпка и да подадете media_url при създаване на публикацията.

POST /api/v1/projects/{project_id}/media/import
curl https://www.amaposta.com/api/v1/projects/$PROJECT_ID/media/import \
  -H "Authorization: Bearer $AMAPOSTA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://cdn.example.com/batch-142.mp4"}'

Всяко качване връща медиен обект. Неговият status преминава от pending през processing до ready (или failed с error). След обработка съдържа width, height, duration_ms и миниатюра. Проверявайте периодично GET /api/v1/media/{id} или слушайте за уебхука media.ready. Върнатият url е подписан и важи 12 часа.

Създаване на публикация

POST /api/v1/projects/{project_id}/posts създава една публикация с отделно изпращане за всеки канал. Amaposta я адаптира за всяка платформа: заглавията отиват само там, където има поле за заглавие, а хаштаговете стават етикети в YouTube и текст в останалите платформи.

Създаване на видеопубликация и добавяне в опашката
curl https://www.amaposta.com/api/v1/projects/$PROJECT_ID/posts \
  -H "Authorization: Bearer $AMAPOSTA_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: episode-142" \
  -d @- <<'JSON'
{
  "kind": "video",
  "title": "How we roast a batch in 12 minutes",
  "description": "From green beans to first crack. We filmed one batch start to finish.",
  "hashtags": ["coffee", "behindthescenes"],
  "media_url": "https://cdn.example.com/batch-142.mp4",
  "cover_url": "https://cdn.example.com/batch-142-cover.jpg",
  "overrides": {
    "<x-channel-id>": {
      "description": "Batch 142 is out: green beans to first crack in 12 minutes."
    },
    "<youtube-channel-id>": {
      "options": { "privacy": "unlisted" }
    }
  },
  "schedule": { "mode": "queue" },
  "external_ref": "episode-142",
  "metadata": {
    "pipeline": { "name": "nightly-cut", "run": "2026-10-17" }
  }
}
JSON

Полета

ПолеКакво прави
kindtext, image или video. Задължително.
titleИзползва се от платформи с поле за заглавие: YouTube, фотопубликации в TikTok, видеоклипове във Facebook.
descriptionНадписът, описанието или текстът на публикацията. Приема се също като body, caption или text.
hashtagsСписък със или без #.
media_id, media_urlИдентификатор на качен медиен файл или публичен URL адрес, от който Amaposta го изтегля. Нужен е за публикации с изображения и видеоклипове.
cover_media_id, cover_urlКорица за видеоклипове, когато платформата я поддържа.
channelsИдентификатори на каналите за публикуване. Пропуснете ги, за да използвате всички активни канали в проекта, които поддържат този вид публикация.
overridesПромени за отделни канали с ключ идентификатора на канала: title, description, hashtags и options за платформата, като privacy на YouTube.
schedulemode е at (с at в ISO 8601), now или queue за следващия свободен час за публикуване. Пропуснете го, за да създадете чернова.
external_refВаша собствена референция, връщана в публикацията и при изпращанията към Custom API.
metadataJSON със свободна структура, съхраняван с публикацията. Включете "pipeline", за да отбележите генерирано съдържание; таблото го показва, а уебхуковете посочват произхода като pipeline.

Отговорът е публикацията, включително по един запис в deliveries за всеки канал.

Безопасни повторни опити

Мрежите губят заявки. Изпращайте заглавка Idempotency-Key при създаване на публикация и повторен опит със същия ключ ще върне публикацията от първия опит, вместо да създава втора. Използвайте постоянна стойност от ваша страна, като идентификатор на задача или епизод. Ключовете се отрязват до 200 знака.

Насрочване и публикуване

Насрочете чернова, публикувайте я веднага, добавете я в опашката или я махнете от календара с POST /api/v1/posts/{post_id}/schedule.

Насрочване за час
curl https://www.amaposta.com/api/v1/posts/$POST_ID/schedule \
  -H "Authorization: Bearer $AMAPOSTA_KEY" \
  -H "Content-Type: application/json" \
  -d '{"mode": "at", "at": "2026-10-20T07:00:00Z"}'
  • atПубликува в зададения час, до две години напред.
  • nowПубликува веднага.
  • queueЗаема следващия свободен час за публикуване за каналите на публикацията в следващите 12 седмици.
  • unscheduleВръща публикацията в черновите.

Преди всяко насрочване се изпълняват същите проверки като в редактора. При неуспешна проверка заявката връща 400 със съобщение като Поправете преди насрочване: YouTube изисква заглавие. Насрочването изисква правото posts:publish или проект с включени одобрения, при което публикацията чака във входящата кутия за преглед.

Четене на публикации и изпращания

Избройте публикациите в проект, филтрирани по status (статуси, разделени със запетая, или inbox, queue или history), интервал from/to, limit и offset. Отговорът е {"items": […], "total": n}.

Какво предстои и една публикация в подробности
curl "https://www.amaposta.com/api/v1/projects/$PROJECT_ID/posts?status=queue" \
  -H "Authorization: Bearer $AMAPOSTA_KEY"

curl https://www.amaposta.com/api/v1/posts/$POST_ID \
  -H "Authorization: Bearer $AMAPOSTA_KEY"

Публикацията има общ status (draft, in_review, changes_requested, ready, scheduled, publishing, published, partial или failed) и по едно изпращане за всеки канал:

deliveries[]
"deliveries": [
  {
    "id": "0192b7d4-…",
    "channel_id": "0192b7a1-…",
    "status": "published",
    "url": "https://www.youtube.com/watch?v=…",
    "error": null,
    "published_at": "2026-10-20T07:00:41Z"
  },
  {
    "id": "0192b7d4-…",
    "channel_id": "0192b7a9-…",
    "status": "failed",
    "url": null,
    "error": {
      "code": "endpoint_unavailable",
      "message": "Your endpoint returned 503 Service Unavailable",
      "hint": "Amaposta will retry with backoff."
    },
    "published_at": null
  }
]

Статусите на изпращане са pending, scheduled, publishing, processing, published, failed и cancelled. DELETE /api/v1/posts/{post_id} премахва публикация.

Грешки

Всяка грешка има еднакъв формат: обект error с постоянен code, message, което можете да показвате на хората, а понякога и fields (съобщения за отделните полета) и hint.

422 Unprocessable Entity
{
  "error": {
    "code": "validation",
    "message": "Please fix the highlighted fields.",
    "fields": {
      "kind": "Use text, image or video."
    }
  }
}
СтатусКодЗначение
400bad_requestЗаявката не може да се изпълни според искането, например насрочване на публикация с неуспешни проверки.
401unauthorizedAPI ключът липсва, грешен е или е отменен.
402plan_limitПланът на работното пространство не позволява това; limit посочва кое ограничение.
403forbiddenКлючът няма нужното право или достъп до проекта.
404not_foundНяма такъв проект, публикация, медиен файл или крайна точка.
409conflictПромяната е несъвместима с текущото състояние, например редактиране на публикация, която вече се публикува.
422validationЕдно или повече полета се нуждаят от поправка; вижте fields.
429rate_limitedНад 120 заявки в минута с този ключ.
502provider_errorПлатформа отказа или възникна грешка; hint посочва какво да направите.

Уебхукове

Добавете крайна точка в Настройки, API и уебхукове, изберете желаните събития и копирайте тайната ѝ за подписване. За всяко събитие Amaposta изпраща JSON с POST към вашия URL адрес. При отговор, различен от 2xx, или липса на отговор в рамките на 15 секунди, опитът се повтаря с нарастващо изчакване. Крайни точки, които продължават да дават грешки, се изключват с известие до администраторите.

СъбитиеИзпраща се при
post.createdПубликация беше създадена (от таблото или API)
post.scheduledПубликация беше насрочена
post.approvedПубликация беше одобрена
post.publishedПубликация излезе в канал
post.failedПубликация не беше публикувана успешно в канал
channel.connectedКанал беше свързан или свързан повторно
channel.disconnectedКанал загуби връзката си
media.readyОбработката на качен файл приключи
media.failedКачен файл не можа да бъде обработен
post.published
POST /your/webhook HTTP/1.1
Content-Type: application/json
User-Agent: Amaposta-Webhooks/1.0
X-Amaposta-Event: post.published
X-Amaposta-Event-Id: 0192b7e0-…
X-Amaposta-Signature: t=1792479641,v1=5f2b0c…

{
  "id": "0192b7e0-…",
  "type": "post.published",
  "created_at": "2026-10-20T07:00:41Z",
  "project_id": "0192a3f1-…",
  "data": {
    "post_id": "0192b7c8-…",
    "delivery_id": "0192b7d4-…",
    "channel_id": "0192b7a1-…",
    "provider": "youtube",
    "external_id": "…",
    "url": "https://www.youtube.com/watch?v=…"
  }
}

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

X-Amaposta-Signature е t=<unix seconds>,v1=<hex>, където v1 е HMAC_SHA256(secret, t + "." + body) върху необработеното тяло на заявката. Изчислете го самостоятелно, сравнете за константно време и отхвърляйте стари времеви отметки, за да предотвратите повторно изпращане.

Node.js
import crypto from "node:crypto";

// rawBody: the request body exactly as received (string or Buffer).
export function verifySignature(rawBody, header, secret, toleranceSeconds = 300) {
  const parts = Object.fromEntries(header.split(",").map((p) => p.split("=", 2)));
  const t = Number(parts.t);
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${t}.${rawBody}`)
    .digest();
  const given = Buffer.from(parts.v1 ?? "", "hex");
  return given.length === expected.length && crypto.timingSafeEqual(given, expected);
}
Python
import hashlib
import hmac
import time


def verify_signature(raw_body: bytes, header: str, secret: str, tolerance: int = 300) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    t = int(parts.get("t", "0"))
    if abs(time.time() - t) > tolerance:
        return False
    expected = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts.get("v1", ""))

Канали Custom API

Каналът Custom API публикува към HTTPS крайна точка, която управлявате: вашата CMS, инструмент за бюлетини или платформа, която Amaposta още не поддържа. Той се показва в календара и преминава през проверки, одобрения и повторни опити като всеки друг канал. При публикуване Amaposta изпраща по една POST заявка за всяко изпращане:

Какво получава вашата крайна точка
POST /amaposta/publish HTTP/1.1
Authorization: Bearer <your API key>
Content-Type: application/json
Idempotency-Key: 0192b7d4-…
X-Amaposta-Delivery: 0192b7d4-…
X-Amaposta-Signature: t=1792479600,v1=9ac41e…

{
  "id": "0192b7d4-…",
  "type": "post.publish",
  "created_at": "2026-10-20T07:00:00Z",
  "content": {
    "kind": "video",
    "title": "How we roast a batch in 12 minutes",
    "text": "From green beans to first crack. We filmed one batch start to finish.",
    "hashtags": ["coffee", "behindthescenes"],
    "media": {
      "url": "https://…",
      "content_type": "video/mp4",
      "size_bytes": 48213844,
      "width": 1080,
      "height": 1920,
      "duration_ms": 58000,
      "filename": "batch-142.mp4"
    },
    "cover": null,
    "options": {}
  },
  "post": {
    "id": "0192b7c8-…",
    "external_ref": "episode-142",
    "scheduled_at": "2026-10-20T07:00:00Z",
    "metadata": {
      "pipeline": { "name": "nightly-cut" }
    }
  },
  "project": { "id": "0192a3f1-…", "name": "Spring launch" },
  "channel": { "id": "0192b7a9-…", "name": "api.example.com" }
}

Как да отговорите

  • 2xxПубликувано. По избор върнете {"id": "…", "url": "…"} и връзката ще се покаже в публикацията.
  • 401, 403Ключът е отхвърлен. Каналът се отбелязва за повторно свързване и администраторите се уведомяват. Не използвайте тези статуси за невалиден подпис.
  • 5xx, 408, 429Временно. Amaposta повтаря с нарастващо изчакване.
  • Други 4xxПубликацията се отбелязва като неуспешна с вашето съобщение и някой може да я поправи и да натисне Повторен опит.
Получател в Express
app.post("/amaposta/publish", express.raw({ type: "application/json" }), async (req, res) => {
  const signature = req.get("X-Amaposta-Signature") ?? "";
  if (!verifySignature(req.body, signature, process.env.AMAPOSTA_SIGNING_SECRET)) {
    return res.status(400).json({ message: "Bad signature" });
  }
  const delivery = JSON.parse(req.body);
  const item = await publishToYourSystem(delivery.content, req.get("Idempotency-Key"));
  res.json({ id: item.id, url: item.url });
});

Крайната ви точка трябва да е достъпна от интернет; пренасочвания не се следват. При свързване на канала Amaposta я проверява с GET към URL адреса за изправност, ако сте задали такъв, или с OPTIONS заявка към крайната точка.

Канали Sandbox

Каналът Sandbox се държи като истински, но нищо не напуска Amaposta. Използвайте го, за да изградите и тествате интеграцията си от край до край: публикациите се насрочват, излизат в ефир, публикуват се или се провалят и задействат същите уебхукове. Каналите Sandbox са безплатни във всеки план и не се броят към ограниченията за канали.

Изберете как да се държи при добавяне:

  • Винаги успехВсяка публикация се публикува.
  • Неуспех от време на времеИзпробвайте неуспехи и повторни опити, без да чакате истински срив.
  • Винаги неуспехТествайте обработката на post.failed.
  • Изтекла връзкаВижте как изглеждат сигналите и връзките за повторно свързване, когато достъпът изтече.

Правила на платформата

Какво приема всеки вид канал. Проверките използват същите ограничения, затова повечето проблеми се откриват преди насрочването на публикацията, а не при публикуване.

Платформа Публикация Заглавие Текст Хаштагове Медийни файлове
YouTube Видео ЗаглавиеЗадължително, до 100 знака ОписаниеДо 5000 знака Изпращат се като етикети, до 60 MP4, MOV, WebM, AVI, MKV; до 256 GB; от 1 сек до 12 ч
Акаунти без потвърден телефонен номер могат да качват до 15 минути и не могат да задават собствени миниатюри. Всяко качване изразходва квота за API; стандартната квота на Google позволява около шест качвания на ден за приложение.
Instagram Изображение Без заглавие НадписДо 2200 знака Добавят се към текста, до 30 JPEG; до 8 MB
Видео Без заглавие НадписДо 2200 знака Добавят се към текста, до 30 MP4, MOV; до 300 MB; от 3 сек до 15 мин
Изисква се Instagram Business или Creator акаунт. Instagram позволява 50 публикации чрез API на акаунт за всеки подвижен период от 24 часа. Публикации само с текст не са възможни в Instagram.
TikTok Изображение ЗаглавиеДо 90 знака ОписаниеДо 4000 знака Добавят се към текста JPEG, WebP; до 20 MB
Видео Без заглавие НадписДо 2200 знака Добавят се към текста MP4, MOV, WebM; до 4 GB; от 3 сек до 10 мин
Публикациите от приложения, които не са преминали проверката на TikTok, са видими само за създателя. TikTok избира корицата от кадър на видеоклипа; собствени изображения за корица не се поддържат. Публикации само с текст не са възможни в TikTok.
X Текст Без заглавие ПубликацияЗадължително, до 280 (връзките са 23 знака, емоджитата — 2) Добавят се към текста Няма
Изображение Без заглавие ПубликацияДо 280 (връзките са 23 знака, емоджитата — 2) Добавят се към текста JPEG, PNG, WebP, GIF; до 5 MB
Видео Без заглавие ПубликацияДо 280 (връзките са 23 знака, емоджитата — 2) Добавят се към текста MP4, MOV; до 512 MB; от 0,5 сек до 2:20 мин
Ако използвате собствено приложение за разработчици на X, публикациите изразходват неговите API кредити с плащане според потреблението. Хаштаговете се броят към ограничението за знаци.
Facebook Текст Без заглавие ПубликацияЗадължително, до 63 206 знака Добавят се към текста Няма
Изображение Без заглавие НадписДо 63 206 знака Добавят се към текста JPEG, PNG, GIF, WebP; до 10 MB
Видео ЗаглавиеДо 255 знака ОписаниеДо 63 206 знака Добавят се към текста MP4, MOV; до 1 GB; от 1 сек до 20 мин
Публикува само в страници; личните профили не позволяват публикуване чрез API.
Custom API Текст ЗаглавиеБез ограничение за дължината ОписаниеБез ограничение за дължината Изпращат се като етикети Няма
Изображение ЗаглавиеБез ограничение за дължината ОписаниеБез ограничение за дължината Изпращат се като етикети JPEG, PNG, WebP, GIF
Видео ЗаглавиеБез ограничение за дължината ОписаниеБез ограничение за дължината Изпращат се като етикети MP4, MOV, WebM
Всяка заявка е подписана със заглавка HMAC-SHA256, за да проверите, че идва от Amaposta. Отговорете с 2xx и по избор JSON {"id": "…", "url": "…"}. Отговори 408, 429 и 5xx се повтарят с нарастващо изчакване; 401/403 отбелязват канала за повторно свързване; други 4xx провалят изпращането, за да го поправите и повторите.
Sandbox Текст ЗаглавиеДо 200 знака ОписаниеДо 5000 знака Добавят се към текста, до 30 Няма
Изображение ЗаглавиеДо 200 знака ОписаниеДо 5000 знака Добавят се към текста, до 30 JPEG, PNG, WebP, GIF
Видео ЗаглавиеДо 200 знака ОписаниеДо 5000 знака Добавят се към текста, до 30 MP4, MOV, WebM
Публикуването отнема малко време, за да наблюдавате промяната на статуса на живо.