Автентифікація
Створіть ключ 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. Найкраще для файлів до кількох сотень МБ.
curl https://www.amaposta.com/api/v1/projects/$PROJECT_ID/media \
-H "Authorization: Bearer $AMAPOSTA_KEY" \
-F "[email protected]"
Завантаження великих файлів за попередньо підписаною URL-адресою
Запросіть 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 під час створення допису.
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
Поля
| Поле | Що робить |
|---|---|
kind | text, 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. |
schedule | mode може бути at (з at у форматі ISO 8601), now або queue для наступного вільного вікна публікації. Не вказуйте це поле, щоб створити чернетку. |
external_ref | Ваш власний ідентифікатор, що повертається в дописі й надсиланнях до власного API. |
metadata | JSON довільної структури, що зберігається з дописом. Додайте "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": [
{
"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.
{
"error": {
"code": "validation",
"message": "Please fix the highlighted fields.",
"fields": {
"kind": "Use text, image or video."
}
}
}
| Статус | Код | Значення |
|---|---|---|
| 400 | bad_request | Запит неможливо виконати в зазначеному вигляді, наприклад запланувати допис, який не пройшов перевірки. |
| 401 | unauthorized | Ключ API відсутній, неправильний або відкликаний. |
| 402 | plan_limit | Тариф робочого простору не дозволяє цю дію; limit указує, який саме ліміт. |
| 403 | forbidden | Ключ не має потрібного дозволу або доступу до проєкту. |
| 404 | not_found | Такого проєкту, допису, медіафайлу або кінцевої точки немає. |
| 409 | conflict | Зміна суперечить поточному стану, наприклад редагування допису, який уже публікується. |
| 422 | validation | Одне або кілька полів потрібно виправити; дивіться fields. |
| 429 | rate_limited | Понад 120 запитів на хвилину для цього ключа. |
| 502 | provider_error | Платформа відхилила запит або сталася помилка; hint підказує, що робити. |
Вебхуки
Додайте кінцеву точку в розділі «Налаштування → API та вебхуки», виберіть потрібні події та скопіюйте секрет підпису. Amaposta надсилає POST із JSON на вашу URL-адресу для кожної події. Якщо відповідь відрізняється від 2xx або не надходить протягом 15 секунд, спроби повторюються зі збільшенням інтервалу. Кінцеві точки з постійними збоями вимикаються зі сповіщенням адміністраторів.
| Подія | Надсилається, коли |
|---|---|
post.created | Допис створено (у панелі керування або через API) |
post.scheduled | Допис заплановано |
post.approved | Допис погоджено |
post.published | Допис опубліковано в каналі |
post.failed | Не вдалося опублікувати допис у каналі |
channel.connected | Канал під’єднано або під’єднано повторно |
channel.disconnected | Канал утратив з’єднання |
media.ready | Обробку завантаженого файлу завершено |
media.failed | Не вдалося обробити завантажений файл |
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) для необробленого тіла запиту. Обчисліть підпис самостійно, порівняйте за сталий час і відхиляйте старі часові позначки, щоб запобігти повторному відтворенню запитів.
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);
}
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", ""))
Канали з власним API
Канал із власним 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" }
}
Authorization- Ваш ключ API. Назва заголовка й префікс (
Bearerза замовчуванням) задаються в каналі. Idempotency-Key- Ідентифікатор надсилання. Повторна спроба того самого надсилання містить той самий ключ, тож ви можете пропустити вже виконану роботу.
X-Amaposta-Delivery- Ідентифікатор надсилання ще раз, для ваших журналів.
X-Amaposta-Signature- Підписується як вебхуки, з власним секретом підпису каналу.
Як відповідати
- 2xxОпубліковано. За бажанням поверніть
{"id": "…", "url": "…"}, і посилання з’явиться в дописі. - 401, 403Ключ відхилено. Канал позначається як такий, що потребує повторного під’єднання, а адміністратори отримують сповіщення. Не використовуйте ці коди для неправильного підпису.
- 5xx, 408, 429Тимчасова проблема. Amaposta повторює спроби зі збільшенням інтервалу.
- Інші 4xxДопис позначається як невдалий із вашим повідомленням; хтось зможе виправити його й натиснути «Повторити».
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
Канал-пісочниця працює як справжній, але нічого не виходить за межі Amaposta. Використовуйте його, щоб створити й перевірити інтеграцію від початку до кінця: дописи плануються, виходять в ефір, публікуються або зазнають збою та викликають ті самі вебхуки. Канали-пісочниці безкоштовні в усіх тарифах і не враховуються в лімітах каналів.
Виберіть, як канал поводитиметься після додавання:
- Завжди успіхКожен допис публікується.
- Іноді збійПерегляньте збої та повторні спроби, не чекаючи справжньої аварії.
- Завжди збійПеревірте обробку
post.failed. - Строк з’єднання закінчивсяПодивіться, як виглядають сповіщення й посилання для повторного під’єднання після закінчення доступу.
Правила платформ
Що приймає кожен тип каналу. Перевірки використовують ті самі ліміти, тож більшість проблем виявляється до планування допису, а не під час публікації.
| Платформа | Допис | Заголовок | Текст | Хештеги | Медіафайли |
|---|---|---|---|---|---|
| YouTube | Відео | ЗаголовокОбов’язково, до 100 символів | ОписДо 5 000 символів | Надсилаються як теги, до 60 | MP4, MOV, WebM, AVI, MKV; до 256 GB; Від 1 с до 12 год |
| Облікові записи без підтвердженого номера телефону можуть завантажувати відео тривалістю до 15 хвилин і не можуть задавати власні мініатюри. Кожне завантаження витрачає квоту API; стандартна квота Google дозволяє приблизно шість завантажень на день для кожного застосунку. | |||||
| Зображення | Без заголовка | ПідписДо 2 200 символів | Додаються до тексту, до 30 | JPEG; до 8 MB | |
| Відео | Без заголовка | ПідписДо 2 200 символів | Додаються до тексту, до 30 | MP4, MOV; до 300 MB; Від 3 с до 15 хв | |
| Потрібен обліковий запис Instagram Business або Creator. Instagram дозволяє публікувати через API 50 дописів на обліковий запис за будь-які послідовні 24 години. Суто текстові дописи неможливі в Instagram. | |||||
| TikTok | Зображення | ЗаголовокДо 90 символів | ОписДо 4 000 символів | Додано до тексту | JPEG, WebP; до 20 MB |
| Відео | Без заголовка | ПідписДо 2 200 символів | Додано до тексту | 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 з оплатою за використання. Хештеги враховуються в ліміті символів. | |||||
| Текст | Без заголовка | ДописОбов’язково, до 63 206 символів | Додано до тексту | Немає | |
| Зображення | Без заголовка | ПідписДо 63 206 символів | Додано до тексту | JPEG, PNG, GIF, WebP; до 10 MB | |
| Відео | ЗаголовокДо 255 символів | ОписДо 63 206 символів | Додано до тексту | MP4, MOV; до 1 GB; Від 1 с до 20 хв | |
| Публікує лише на сторінках; публікація в особисті профілі через API неможлива. | |||||
| Власний API | Текст | ЗаголовокБез обмеження довжини | ОписБез обмеження довжини | Надсилаються як теги | Немає |
| Зображення | ЗаголовокБез обмеження довжини | ОписБез обмеження довжини | Надсилаються як теги | JPEG, PNG, WebP, GIF | |
| Відео | ЗаголовокБез обмеження довжини | ОписБез обмеження довжини | Надсилаються як теги | MP4, MOV, WebM | |
| Кожен запит підписано заголовком HMAC-SHA256, щоб ви могли перевірити, що він надійшов від Amaposta. Дайте відповідь 2xx і, за бажанням, JSON {"id": "…", "url": "…"}. Відповіді 408, 429 і 5xx спричиняють повторні спроби зі збільшенням інтервалу; 401/403 позначають канал як такий, що потребує повторного під’єднання; інші 4xx завершують надсилання помилкою, щоб ви могли виправити її й повторити спробу. | |||||
| Sandbox | Текст | ЗаголовокДо 200 символів | ОписДо 5 000 символів | Додаються до тексту, до 30 | Немає |
| Зображення | ЗаголовокДо 200 символів | ОписДо 5 000 символів | Додаються до тексту, до 30 | JPEG, PNG, WebP, GIF | |
| Відео | ЗаголовокДо 200 символів | ОписДо 5 000 символів | Додаються до тексту, до 30 | MP4, MOV, WebM | |
| Публікація триває трохи часу, щоб ви могли побачити зміну статусу наживо. | |||||