Hoppa till innehållet

Utvecklarguide

Skicka inlägg till Amaposta från ditt eget innehållsflöde: ladda upp media, skapa ett inlägg för alla kanaler, schemalägg det och få besked när det är publicerat.

Autentisering

Skapa en API-nyckel i kontrollpanelen under Inställningar, API och webhooks. Nycklar börjar med ss_live_, hör till en arbetsyta och kan begränsas till vissa projekt. Skicka nyckeln som en bearer-token med varje begäran:

Kontrollera en nyckel
curl https://www.amaposta.com/api/v1/me \
  -H "Authorization: Bearer ss_live_…"

Svaret anger nyckelns namn, dess behörigheter och arbetsytan. Varje nyckel har en eller flera behörigheter:

BehörighetTillåter
content:readLäs projekt, kanaler, inlägg och media.
content:writeLadda upp media och skapa eller redigera inlägg.
posts:publishSchemalägg och publicera utan granskning. Utan denna behörighet går inlägg till granskningsinkorgen i projekt som använder godkännanden och förblir utkast överallt annars.

Varje nyckel kan göra 120 anrop per minut. Därefter får du 429 med koden rate_limited; vänta en stund och försök igen.

Projekt och kanaler

Inlägg hör till ett projekt. Lista projekten som din nyckel kan se och sedan kanalerna i ett av dem. Du behöver en kanals ID för att välja den som mål eller anpassa dess text.

Lista projekt och kanaler
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"

En kanal har en provider (youtube, instagram, tiktok, x, facebook, custom eller sandbox), en status (active, expiring, needs_reconnect, error eller disabled) och inläggstyper som den supports.

Ladda upp media

Bilder och videor laddas upp en gång per projekt och kan användas i valfritt antal inlägg. Det finns tre sätt att göra det.

Direktuppladdning

Skicka filen som multipart-formulärdata i ett fält med namnet file. Passar bäst för filer upp till några hundra 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]"

Försignerad uppladdning för stora filer

Begär en uppladdnings-URL, skicka byten direkt till lagringen med PUT och meddela sedan Amaposta att du är klar.

Tre begäranden
# 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"

Importera från en URL

Ge Amaposta en offentlig URL så hämtas filen i bakgrunden. Du kan också hoppa över detta steg och ange media_url när du skapar inlägget.

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"}'

Varje uppladdning returnerar ett mediaobjekt. Dess status går från pending till processing till ready (eller failed, med ett error). Efter bearbetningen innehåller det width, height, duration_ms och en miniatyrbild. Polla GET /api/v1/media/{id} eller lyssna efter webhooken media.ready. Den url som returneras är signerad och giltig i 12 timmar.

Skapa ett inlägg

POST /api/v1/projects/{project_id}/posts skapar ett inlägg med en leverans för varje kanal. Amaposta anpassar det till varje plattform: titlar används bara där det finns ett titelfält, hashtaggar blir taggar på YouTube och löpande text på övriga plattformar.

Skapa ett videoinlägg och lägg det i kön
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

Fält

FältVad den gör
kindtext, image eller video. Obligatoriskt.
titleAnvänds av plattformar med ett titelfält: YouTube, TikToks bildinlägg, Facebook-videor.
descriptionBildtexten, beskrivningen eller inläggstexten. Kan även anges som body, caption eller text.
hashtagsEn lista, med eller utan #.
media_id, media_urlEtt ID för uppladdat media, eller en offentlig URL som Amaposta hämtar åt dig. Krävs för bild- och videoinlägg.
cover_media_id, cover_urlEn omslagsbild för videor, där plattformen stöder det.
channelsID:n för kanaler att publicera till. Utelämna detta för att använda alla aktiva kanaler i projektet som stöder den här typen av inlägg.
overridesÄndringar per kanal med kanal-ID som nyckel: title, description, hashtags och plattformens options, till exempel YouTubes privacy.
schedulemode är at (med ett ISO 8601-värde i at), now eller queue för nästa lediga publiceringstid. Utelämna det för att skapa ett utkast.
external_refDin egen referens, som återges i inlägget och i leveranser till anpassade API:er.
metadataJSON med valfri struktur som lagras med inlägget. Inkludera "pipeline" för att märka genererat innehåll; kontrollpanelen visar det och webhooks anger ursprunget som pipeline.

Svaret är inlägget, inklusive en post i deliveries per kanal.

Säkra återförsök

Begäranden kan försvinna i nätverket. Skicka en Idempotency-Key-header när du skapar ett inlägg, så returnerar ett nytt försök med samma nyckel inlägget från det första försöket i stället för att skapa ett till. Använd något stabilt från ditt system, till exempel ett jobb- eller avsnitts-ID. Nycklar kapas vid 200 tecken.

Schemalägg och publicera

Schemalägg ett utkast, publicera det direkt, lägg det i kön eller ta bort det från kalendern med POST /api/v1/posts/{post_id}/schedule.

Schemalägg till en tid
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"}'
  • atPublicerar vid den angivna tiden, upp till två år i förväg.
  • nowPublicerar direkt.
  • queueVäljer nästa lediga publiceringstid för inläggets kanaler under de kommande 12 veckorna.
  • unscheduleFlyttar tillbaka inlägget till utkast.

Innan något schemaläggs körs samma kontroller som i redigeraren. Om någon misslyckas returnerar begäran 400 med ett meddelande som Åtgärda detta före schemaläggning: YouTube behöver en titel. Schemaläggning kräver behörigheten posts:publish, eller ett projekt med godkännanden aktiverade, där inlägget då väntar i granskningsinkorgen.

Läs inlägg och leveranser

Lista ett projekts inlägg, filtrerade efter status (kommaseparerade statusvärden, eller inbox, queue eller history), ett intervall med from/to, limit och offset. Svaret är {"items": […], "total": n}.

Vad som kommer härnäst och ett inlägg i detalj
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"

Ett inlägg har en övergripande status (draft, in_review, changes_requested, ready, scheduled, publishing, published, partial eller failed) och en leverans per 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
  }
]

Leveransstatus är pending, scheduled, publishing, processing, published, failed och cancelled. DELETE /api/v1/posts/{post_id} tar bort ett inlägg.

Fel

Alla fel har samma form: ett error-objekt med en stabil code, ett message som du kan visa för användare och ibland fields (meddelanden per fält) och en hint.

422 Unprocessable Entity
{
  "error": {
    "code": "validation",
    "message": "Please fix the highlighted fields.",
    "fields": {
      "kind": "Use text, image or video."
    }
  }
}
StatusKodBetydelse
400bad_requestBegäran kan inte genomföras som angivet, till exempel schemaläggning av ett inlägg som inte klarar kontrollerna.
401unauthorizedAPI-nyckeln saknas, är felaktig eller har återkallats.
402plan_limitArbetsytans abonnemang tillåter inte detta; limit anger vilken gräns som gäller.
403forbiddenNyckeln saknar en behörighet eller åtkomst till projektet.
404not_foundInget sådant projekt, inlägg, media eller ändpunkt.
409conflictÄndringen är oförenlig med det aktuella tillståndet, till exempel redigering av ett inlägg som redan håller på att publiceras.
422validationEtt eller flera fält behöver rättas; se fields.
429rate_limitedFler än 120 anrop per minut med den här nyckeln.
502provider_errorEn plattform avvisade begäran eller misslyckades; hint anger vad du kan göra.

Webhooks

Lägg till en ändpunkt under Inställningar, API och webhooks, välj önskade händelser och kopiera dess signeringshemlighet. Amaposta skickar JSON med POST till din URL för varje händelse. Alla svar utom 2xx, eller uteblivna svar inom 15 sekunder, leder till nya försök med ökande väntetid. Ändpunkter som fortsätter att misslyckas stängs av och administratörer meddelas.

HändelseSkickas när
post.createdEtt inlägg skapades (kontrollpanel eller API)
post.scheduledEtt inlägg schemalades
post.approvedEtt inlägg godkändes
post.publishedEtt inlägg publicerades på en kanal
post.failedEtt inlägg kunde inte publiceras på en kanal
channel.connectedEn kanal anslöts eller återanslöts
channel.disconnectedEn kanal förlorade anslutningen
media.readyEn uppladdning har bearbetats klart
media.failedEn uppladdning kunde inte bearbetas
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=…"
  }
}

Verifiera signaturen

X-Amaposta-Signature är t=<unix seconds>,v1=<hex>, där v1 är HMAC_SHA256(secret, t + "." + body) beräknat på den obearbetade begärandekroppen. Beräkna den själv, jämför i konstant tid och avvisa gamla tidsstämplar för att förhindra återuppspelning.

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

Kanaler med anpassat API

En kanal med anpassat API publicerar till en HTTPS-ändpunkt som du driver: ditt CMS, ett nyhetsbrevsverktyg eller en plattform som Amaposta ännu inte stöder. Den finns i kalendern och får kontroller, godkännanden och nya försök precis som alla andra kanaler. När ett inlägg publiceras skickar Amaposta en POST per leverans:

Vad din ändpunkt tar emot
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" }
}

Så svarar du

  • 2xxPublicerat. Returnera eventuellt {"id": "…", "url": "…"} så visas länken på inlägget.
  • 401, 403Nyckeln avvisades. Kanalen markeras för återanslutning och administratörer meddelas. Använd inte dessa svar vid felaktig signatur.
  • 5xx, 408, 429Tillfälligt. Amaposta försöker igen med ökande väntetid.
  • Andra 4xxInlägget markeras som misslyckat med ditt meddelande, så att någon kan åtgärda det och trycka på Försök igen.
En mottagare i 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 });
});

Din ändpunkt måste gå att nå från internet; omdirigeringar följs inte. När du ansluter kanalen kontrollerar Amaposta den med GET till din kontroll-URL om du har angett en, annars med en OPTIONS-begäran till ändpunkten.

Sandbox-kanaler

En sandbox-kanal fungerar som en riktig kanal, men ingenting lämnar Amaposta. Använd den för att bygga och testa hela din integration: inlägg schemaläggs, sänds, publiceras eller misslyckas och utlöser samma webhooks. Sandbox-kanaler är gratis med alla abonnemang och räknas inte mot kanalgränsen.

Välj hur den ska fungera när du lägger till den:

  • Lyckas alltidAlla inlägg publiceras.
  • Misslyckas då och dåSe fel och nya försök utan att vänta på ett riktigt avbrott.
  • Misslyckas alltidTesta din hantering av post.failed.
  • Utgången anslutningSe hur aviseringar och länkar för återanslutning ser ut när åtkomsten löper ut.

Plattformsregler

Vad varje kanaltyp tar emot. Kontrollerna använder samma gränser, så de flesta problem syns innan ett inlägg schemaläggs i stället för vid publiceringen.

Plattform Inlägg Titel Text Hashtaggar Media
YouTube Video TitelObligatoriskt, upp till 100 tecken BeskrivningUpp till 5 000 tecken Skickas som taggar, upp till 60 MP4, MOV, WebM, AVI, MKV; upp till 256 GB; 1 s till 12 h
Konton som inte har verifierat ett telefonnummer kan ladda upp upp till 15 minuter och kan inte ange egna miniatyrbilder. Varje uppladdning förbrukar API-kvot; Googles standardkvot medger ungefär sex uppladdningar per dag och app.
Instagram Bild Ingen titel BildtextUpp till 2 200 tecken Läggs till i texten, upp till 30 JPEG; upp till 8 MB
Video Ingen titel BildtextUpp till 2 200 tecken Läggs till i texten, upp till 30 MP4, MOV; upp till 300 MB; 3 s till 15 min
Kräver ett Instagram Business- eller Creator-konto. Instagram tillåter 50 API-publicerade inlägg per konto under en rullande 24-timmarsperiod. Inlägg med enbart text är inte möjliga på Instagram.
TikTok Bild TitelUpp till 90 tecken BeskrivningUpp till 4 000 tecken Läggs till i texten JPEG, WebP; upp till 20 MB
Video Ingen titel BildtextUpp till 2 200 tecken Läggs till i texten MP4, MOV, WebM; upp till 4 GB; 3 s till 10 min
Inlägg från appar som inte har slutfört TikToks granskning är bara synliga för skaparen. TikTok väljer omslaget från en videobildruta; egna omslagsbilder stöds inte. Inlägg med enbart text är inte möjliga på TikTok.
X Text Ingen titel InläggObligatoriskt, upp till 280 (länkar räknas som 23, emoji som 2) Läggs till i texten Inga
Bild Ingen titel InläggUpp till 280 (länkar räknas som 23, emoji som 2) Läggs till i texten JPEG, PNG, WebP, GIF; upp till 5 MB
Video Ingen titel InläggUpp till 280 (länkar räknas som 23, emoji som 2) Läggs till i texten MP4, MOV; upp till 512 MB; 0,5 s till 2:20 min
Med din egen X-utvecklarapp använder inläggen appens API-krediter, som debiteras per användning. Hashtaggar räknas mot teckengränsen.
Facebook Text Ingen titel InläggObligatoriskt, upp till 63 206 tecken Läggs till i texten Inga
Bild Ingen titel BildtextUpp till 63 206 tecken Läggs till i texten JPEG, PNG, GIF, WebP; upp till 10 MB
Video TitelUpp till 255 tecken BeskrivningUpp till 63 206 tecken Läggs till i texten MP4, MOV; upp till 1 GB; 1 s till 20 min
Publicerar bara till sidor; personliga profiler kan inte publiceras till via API:et.
Anpassat API Text TitelIngen längdgräns BeskrivningIngen längdgräns Skickas som taggar Inga
Bild TitelIngen längdgräns BeskrivningIngen längdgräns Skickas som taggar JPEG, PNG, WebP, GIF
Video TitelIngen längdgräns BeskrivningIngen längdgräns Skickas som taggar MP4, MOV, WebM
Varje begäran signeras med en HMAC-SHA256-header så att du kan verifiera att den kommer från Amaposta. Svara med 2xx och eventuellt JSON {"id": "…", "url": "…"}. Svar med 408, 429 och 5xx leder till nya försök med ökande väntetid; 401/403 markerar kanalen för återanslutning; andra 4xx gör att leveransen misslyckas så att du kan åtgärda felet och försöka igen.
Sandbox Text TitelUpp till 200 tecken BeskrivningUpp till 5 000 tecken Läggs till i texten, upp till 30 Inga
Bild TitelUpp till 200 tecken BeskrivningUpp till 5 000 tecken Läggs till i texten, upp till 30 JPEG, PNG, WebP, GIF
Video TitelUpp till 200 tecken BeskrivningUpp till 5 000 tecken Läggs till i texten, upp till 30 MP4, MOV, WebM
Publiceringen tar en stund så att du kan se statusen ändras i realtid.