Preskoči na vsebino

Vodnik za razvijalce

Pošiljaj objave v Amaposto iz svojega vsebinskega cevovoda: naloži predstavnostno datoteko, ustvari objavo za vsak kanal, jo načrtuj in prejmi obvestilo, ko je objavljena.

Preverjanje pristnosti

Na nadzorni plošči pod Nastavitve, API in webhooki ustvari ključ API. Ključi se začnejo z ss_live_, pripadajo enemu delovnemu prostoru in so lahko omejeni na določene projekte. Pošlji ključ kot žeton bearer z vsako zahtevo:

Preveri ključ
curl https://www.amaposta.com/api/v1/me \
  -H "Authorization: Bearer ss_live_…"

Odgovor navede ime ključa, njegova dovoljenja in delovni prostor. Vsak ključ ima enega ali več obsegov dovoljenj:

Obseg dovoljenjDovoljuje
content:readBeri projekte, kanale, objave in predstavnostne datoteke.
content:writeNalagaj predstavnostne datoteke ter ustvarjaj ali urejaj objave.
posts:publishNačrtuj in objavljaj brez pregleda. Brez tega dovoljenja gredo objave v predal za pregled v projektih z odobritvami, drugje pa ostanejo osnutki.

Vsak ključ lahko pošlje 120 zahtev na minuto. Nad to mejo prejmeš 429 s kodo rate_limited; počakaj trenutek in poskusi znova.

Projekti in kanali

Objave so v projektu. Pridobi seznam projektov, ki jih tvoj ključ vidi, nato kanale v enem od njih. Za ciljanje kanala ali prilagoditev njegovega besedila potrebuješ njegov ID.

Seznam projektov in kanalov
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"

Kanal ima provider (youtube, instagram, tiktok, x, facebook, custom ali sandbox), status (active, expiring, needs_reconnect, error ali disabled) in podprte vrste objav supports.

Naloži predstavnostne datoteke

Slike in videoposnetke naložiš enkrat na projekt in jih lahko uporabiš v poljubnem številu objav. Na voljo so trije načini.

Neposredno nalaganje

Pošlji datoteko kot multipart form data v polju file. Najprimerneje za datoteke do nekaj sto 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]"

Predhodno podpisano nalaganje za velike datoteke

Zahtevaj URL za nalaganje, z metodo PUT pošlji bajte neposredno v shrambo in nato obvesti Amaposto, da je nalaganje končano.

Tri zahteve
# 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"

Uvozi iz URL-ja

Amaposti podaj javni URL in datoteko bo prenesla v ozadju. Ta korak lahko tudi preskočiš in ob ustvarjanju objave podaš 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"}'

Vsako nalaganje vrne predstavnostni objekt. Njegov status preide iz pending v processing in nato v ready (ali failed z error). Po obdelavi vsebuje width, height, duration_ms in sličico. Periodično preverjaj GET /api/v1/media/{id} ali poslušaj webhook media.ready. Vrnjeni url je podpisan in velja 12 ur.

Ustvari objavo

POST /api/v1/projects/{project_id}/posts ustvari eno objavo z dostavo za vsak kanal. Amaposta jo prilagodi posamezni platformi: naslovi se pošljejo le tja, kjer obstaja polje za naslov, ključniki pa postanejo oznake na YouTubu in besedilo drugje.

Ustvari videoobjavo in jo dodaj v čakalno vrsto
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

Polja

PoljeKaj omogoča
kindtext, image ali video. Obvezno.
titleUporabljajo platforme s poljem za naslov: YouTube, fotografske objave TikTok, videoposnetki Facebook.
descriptionNapis, opis ali besedilo objave. Sprejme se tudi kot body, caption ali text.
hashtagsSeznam z znakom # ali brez njega.
media_id, media_urlID naložene predstavnostne datoteke ali javni URL, s katerega Amaposta prenese datoteko. Obvezno za slikovne in videoobjave.
cover_media_id, cover_urlNaslovna slika za videoposnetke, kjer jo platforma podpira.
channelsID-ji kanalov za objavo. Izpusti jih za uporabo vseh aktivnih kanalov v projektu, ki podpirajo to vrsto objave.
overridesSpremembe za posamezne kanale z ID-jem kanala kot ključem: title, description, hashtags in options platforme, kot je YouTubov privacy.
schedulemode je at (z vrednostjo at v obliki ISO 8601), now ali queue za naslednji prosti termin objave. Izpusti ga, da ustvariš osnutek.
external_refTvoja referenca, vrnjena pri objavi in dostavah Custom API.
metadataPoljuben JSON, shranjen z objavo. Vključi "pipeline" za označevanje ustvarjene vsebine; nadzorna plošča ga prikaže, webhooki pa poročajo o izvoru kot pipeline.

Odgovor je objava, vključno z enim vnosom v deliveries za vsak kanal.

Varni ponovni poskusi

Zahteve se lahko izgubijo v omrežju. Ob ustvarjanju objave pošlji glavo Idempotency-Key in ponovni poskus z istim ključem vrne objavo iz prvega poskusa, namesto da ustvari drugo. Uporabi stalno vrednost iz svojega sistema, na primer ID opravila ali epizode. Ključi se skrajšajo na 200 znakov.

Načrtuj in objavi

Načrtuj osnutek, ga objavi takoj, dodaj v čakalno vrsto ali odstrani s koledarja z POST /api/v1/posts/{post_id}/schedule.

Načrtuj za določen čas
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"}'
  • atObjavi ob določenem času, do dve leti vnaprej.
  • nowObjavi takoj.
  • queueIzbere naslednji prosti termin objave za kanale objave v naslednjih 12 tednih.
  • unschedulePremakne objavo nazaj med osnutke.

Pred načrtovanjem se izvedejo ista preverjanja kot v urejevalniku. Če katero spodleti, zahteva vrne 400 s sporočilom, kot je Pred načrtovanjem odpravi: YouTube potrebuje naslov. Načrtovanje zahteva dovoljenje posts:publish ali projekt z vklopljenimi odobritvami, kjer objava počaka v predalu za pregled.

Beri objave in dostave

Pridobi seznam objav projekta, filtriran po status (statusi, ločeni z vejico, ali inbox, queue ali history), obdobju from/to, limit in offset. Odgovor je {"items": […], "total": n}.

Kaj prihaja in podroben pogled ene objave
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"

Objava ima skupni status (draft, in_review, changes_requested, ready, scheduled, publishing, published, partial ali failed) in eno dostavo na kanal:

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
  }
]

Statusi dostave so pending, scheduled, publishing, processing, published, failed in cancelled. DELETE /api/v1/posts/{post_id} odstrani objavo.

Napake

Vsaka napaka ima enako obliko: objekt error s stalno kodo code, sporočilom message za prikaz uporabnikom in včasih še s fields (sporočili za posamezna polja) ter namigom hint.

422 Unprocessable Entity
{
  "error": {
    "code": "validation",
    "message": "Please fix the highlighted fields.",
    "fields": {
      "kind": "Use text, image or video."
    }
  }
}
StatusKodaPomen
400bad_requestZahteve ni mogoče izvesti na zahtevani način, na primer načrtovati objave, ki ne prestane preverjanj.
401unauthorizedKljuč API manjka, je napačen ali preklican.
402plan_limitPaket delovnega prostora tega ne dovoljuje; limit pove, katera omejitev velja.
403forbiddenKljuč nima dovoljenja ali dostopa do projekta.
404not_foundTak projekt, objava, predstavnostna datoteka ali končna točka ne obstaja.
409conflictSprememba je v sporu s trenutnim stanjem, na primer urejanje objave, ki se že objavlja.
422validationPopraviti je treba eno ali več polj; glej fields.
429rate_limitedVeč kot 120 zahtev na minuto s tem ključem.
502provider_errorPlatforma je zavrnila zahtevo ali odpovedala; hint pove, kaj storiti.

Webhooki

V nastavitvah pod API in webhooki dodaj končno točko, izberi želene dogodke in kopiraj njen skrivni ključ za podpisovanje. Amaposta za vsak dogodek pošlje JSON z zahtevo POST na tvoj URL. Če odgovor ni 2xx ali ga ni v 15 sekundah, se poskus ponovi s postopnim zamikom. Končne točke s ponavljajočimi se napakami se izklopijo, skrbniki pa prejmejo obvestilo.

DogodekPoslano, ko
post.createdObjava je bila ustvarjena (na nadzorni plošči ali prek API-ja)
post.scheduledObjava je bila načrtovana
post.approvedObjava je bila odobrena
post.publishedObjava je bila objavljena na kanalu
post.failedObjave ni bilo mogoče objaviti na kanalu
channel.connectedKanal je bil povezan ali ponovno povezan
channel.disconnectedKanal je izgubil povezavo
media.readyObdelava naložene datoteke je končana
media.failedNaložene datoteke ni bilo mogoče obdelati
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=…"
  }
}

Preveri podpis

X-Amaposta-Signature je t=<unix seconds>,v1=<hex>, pri čemer je v1 HMAC_SHA256(secret, t + "." + body) nad neobdelanim telesom zahteve. Izračunaj ga samostojno, primerjaj v konstantnem času in zavrni stare časovne žige, da preprečiš ponovitve.

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", ""))

Kanali Custom API

Kanal Custom API objavlja na končno točko HTTPS, ki jo upravljaš: tvoj CMS, orodje za e-novice ali platformo, ki je Amaposta še ne podpira. Prikazan je na koledarju in ima preverjanja, odobritve ter ponovne poskuse kot vsak drug kanal. Ko je objava na vrsti, Amaposta za vsako dostavo pošlje eno zahtevo POST:

Kaj prejme tvoja končna točka
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" }
}

Kako odgovoriti

  • 2xxObjavljeno. Po želji vrni {"id": "…", "url": "…"} in povezava se prikaže pri objavi.
  • 401, 403Ključ je bil zavrnjen. Kanal se označi za ponovno povezavo, skrbniki pa so obveščeni. Teh statusov ne uporabljaj za napačen podpis.
  • 5xx, 408, 429Začasno. Amaposta poskusi znova s postopnim zamikom.
  • Drugi 4xxObjava se z vašim sporočilom označi kot neuspešna, nato jo lahko nekdo popravi in pritisne Poskusi znova.
Sprejemnik v ogrodju 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 });
});

Tvoja končna točka mora biti dosegljiva iz interneta; preusmeritvam se ne sledi. Ob povezovanju kanala jo Amaposta preveri z zahtevo GET na URL za preverjanje delovanja, če je nastavljen, sicer z zahtevo OPTIONS na končno točko.

Kanali peskovnika

Kanal peskovnika se vede kot pravi kanal, vendar nič ne zapusti Amaposte. Z njim lahko razviješ in preizkusiš celotno integracijo: objave se načrtujejo, gredo v objavo, uspejo ali spodletijo ter sprožijo iste webhooke. Kanali peskovnika so brezplačni pri vseh paketih in se ne štejejo v omejitev kanalov.

Izberi, kako se vede po dodajanju:

  • Vedno uspeVsaka objava se objavi.
  • Občasno spodletiOglej si napake in ponovne poskuse brez čakanja na pravi izpad.
  • Vedno spodletiPreizkusi obravnavo dogodka post.failed.
  • Potekla povezavaOglej si opozorila in povezave za ponovno povezavo, ko dostop poteče.

Poveži X prek svoje aplikacije

X vsak klic API, vključno z vsako objavo, zaračuna razvijalski aplikaciji, ki ga izvede, in strošek odšteje od njenega predplačanega dobroimetja. Zato X povežeš prek svoje razvijalske aplikacije X: enkrat jo nastavi za vsak delovni prostor, nato pa poveži poljubno število računov X. Z vsakim računom se prijaviš na X, njegove objave pa se plačujejo iz dobroimetja tvoje aplikacije.

Dobro je vedeti

  • Aplikacija se shrani za celoten delovni prostor, njena skrivnost pa je šifrirana. Vsak drug račun X lahko povežeš z enim klikom iz katerega koli projekta.
  • Kanali ohranijo aplikacijo, prek katere so bili povezani. Ob ponovni povezavi kanala, tudi prek povezave za ponovno povezavo za stranko, se znova uporabi ista aplikacija; tvoja stranka je nikoli ne vidi.
  • Če želiš zamenjati aplikacijo, pri povezovanju X izberi »Uporabi drugo aplikacijo«. Če znova ustvariš Client Secret, tam vnesi novega in ponovno poveži svoje kanale X.
  • Konzola X izda žetone samo za račun, ki je lastnik aplikacije. Račune svojih strank povežeš s prijavo prek svoje aplikacije; za svoj račun lahko še vedno ročno vneseš žetone.

Pravila platforme

Kaj sprejema posamezna vrsta kanala. Preverjanja uporabljajo iste omejitve, zato se večina težav pokaže pred načrtovanjem, ne šele ob objavljanju.

Platforma Objava Naslov Besedilo Ključniki Predstavnostne datoteke
YouTube Videoposnetek NaslovObvezno, največ znakov: 100 OpisNajveč znakov: 5000 Poslano kot oznake, največ 60 MP4, MOV, WebM, AVI, MKV; do 256 GB; Od 1 s do 12 h
Računi brez potrjene telefonske številke lahko naložijo videoposnetke do 15 minut in ne morejo nastaviti sličic po meri. Vsako nalaganje porabi kvoto API-ja; privzeta Googlova kvota omogoča približno šest nalaganj na dan na aplikacijo.
Instagram Slika Brez naslova NapisNajveč znakov: 2200 Dodano besedilu, največ 30 JPEG; do 8 MB
Videoposnetek Brez naslova NapisNajveč znakov: 2200 Dodano besedilu, največ 30 MP4, MOV; do 300 MB; Od 3 s do 15 min
Potreben je poslovni ali ustvarjalski račun Instagram. Instagram dovoljuje 50 objav prek API-ja na račun v drsečem 24-urnem obdobju. Objave samo z besedilom na Instagramu niso mogoče.
TikTok Slika NaslovNajveč znakov: 90 OpisNajveč znakov: 4000 Dodano besedilu JPEG, WebP; do 20 MB
Videoposnetek Brez naslova NapisNajveč znakov: 2200 Dodano besedilu MP4, MOV, WebM; do 4 GB; Od 3 s do 10 min
Objave iz aplikacij, ki niso opravile TikTokovega pregleda, so vidne le ustvarjalcu. TikTok izbere naslovnico iz kadra videoposnetka; naslovne slike po meri niso podprte. Objave samo z besedilom na TikToku niso mogoče.
X Besedilo Brez naslova ObjavaObvezno, do 280 (povezave štejejo 23, emodžiji 2) Dodano besedilu Brez
Slika Brez naslova ObjavaDo 280 (povezave štejejo 23, emodžiji 2) Dodano besedilu JPEG, PNG, WebP, GIF; do 5 MB
Videoposnetek Brez naslova ObjavaDo 280 (povezave štejejo 23, emodžiji 2) Dodano besedilu MP4, MOV; do 512 MB; Od 0,5 s do 2:20 min
Pri lastni razvijalski aplikaciji X objave porabljajo njeno dobroimetje API-ja s plačilom po uporabi. Ključniki se štejejo v omejitev znakov.
Facebook Besedilo Brez naslova ObjavaObvezno, največ znakov: 63.206 Dodano besedilu Brez
Slika Brez naslova NapisNajveč znakov: 63.206 Dodano besedilu JPEG, PNG, GIF, WebP; do 10 MB
Videoposnetek NaslovNajveč znakov: 255 OpisNajveč znakov: 63.206 Dodano besedilu MP4, MOV; do 1 GB; Od 1 s do 20 min
Objavlja samo na straneh; objavljanje na osebnih profilih prek API-ja ni mogoče.
Custom API Besedilo NaslovBrez omejitve dolžine OpisBrez omejitve dolžine Poslano kot oznake Brez
Slika NaslovBrez omejitve dolžine OpisBrez omejitve dolžine Poslano kot oznake JPEG, PNG, WebP, GIF
Videoposnetek NaslovBrez omejitve dolžine OpisBrez omejitve dolžine Poslano kot oznake MP4, MOV, WebM
Vsaka zahteva je podpisana z glavo HMAC-SHA256, da lahko preveriš, da jo je poslala Amaposta. Odgovori z 2xx in neobveznim JSON {"id": "…", "url": "…"}. Pri odgovorih 408, 429 in 5xx se poskusi ponovijo s postopnim zamikom; 401/403 označita kanal za ponovno povezavo; drugi 4xx povzročijo neuspešno dostavo, da lahko težavo odpraviš in poskusiš znova.
Peskovnik Besedilo NaslovNajveč znakov: 200 OpisNajveč znakov: 5000 Dodano besedilu, največ 30 Brez
Slika NaslovNajveč znakov: 200 OpisNajveč znakov: 5000 Dodano besedilu, največ 30 JPEG, PNG, WebP, GIF
Videoposnetek NaslovNajveč znakov: 200 OpisNajveč znakov: 5000 Dodano besedilu, največ 30 MP4, MOV, WebM
Objavljanje traja trenutek, da lahko spremembo statusa spremljaš v živo.