Hopp til innhold

Utviklerveiledning

Send innlegg til Amaposta fra din egen innholdspipeline: last opp medier, opprett et innlegg for alle kanaler, planlegg det og få beskjed når det er publisert.

Autentisering

Opprett en API-nøkkel i kontrollpanelet under Innstillinger, API og webhooks. Nøkler begynner med ss_live_, tilhører ett arbeidsområde og kan begrenses til bestemte prosjekter. Send nøkkelen som et bearer-token i hver forespørsel:

Kontroller en nøkkel
curl https://www.amaposta.com/api/v1/me \
  -H "Authorization: Bearer ss_live_…"

Svaret oppgir nøkkelens navn, tilgangsomfang og arbeidsområdet. Hver nøkkel har ett eller flere tilgangsomfang:

TilgangsomfangTillater
content:readLes prosjekter, kanaler, innlegg og medier.
content:writeLast opp medier og opprett eller rediger innlegg.
posts:publishPlanlegg og publiser uten gjennomgang. Uten dette sendes innlegg til gjennomgangsinnboksen i prosjekter som bruker godkjenninger, og forblir utkast alle andre steder.

Hver nøkkel kan gjøre 120 forespørsler i minuttet. Over dette får du 429 med koden rate_limited. Vent litt og prøv igjen.

Prosjekter og kanaler

Innlegg tilhører et prosjekt. List opp prosjektene nøkkelen din kan se, og deretter kanalene i ett av dem. Du trenger kanalens ID for å velge den som mål eller overstyre teksten.

List opp prosjekter og 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) og innleggstypene den supports.

Last opp medier

Bilder og videoer lastes opp én gang per prosjekt og kan brukes i et ubegrenset antall innlegg. Det finnes tre måter å laste opp på.

Direkte opplasting

Send filen som multipart-skjemadata i et felt med navnet file. Best for filer opptil noen hundre 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]"

Forhåndssignert opplasting for store filer

Be om en opplastings-URL, send bytene direkte til lagring med PUT, og gi deretter Amaposta beskjed om at du er ferdig.

Tre forespørsler
# 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"

Importer fra en URL

Gi Amaposta en offentlig URL, så lastes filen ned i bakgrunnen. Du kan også hoppe over dette trinnet og sende media_url når du oppretter innlegget.

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

Hver opplasting returnerer et medieobjekt. Dets status går fra pending til processing til ready (eller failed, med en error). Når det er behandlet, inneholder det width, height, duration_ms og et miniatyrbilde. Spør jevnlig med GET /api/v1/media/{id} eller lytt etter webhooken media.ready. Feltet url som returneres, er signert og gyldig i 12 timer.

Opprett et innlegg

POST /api/v1/projects/{project_id}/posts oppretter ett innlegg med én levering for hver kanal. Amaposta tilpasser det per plattform: titler sendes bare dit det finnes et tittelfelt, og emneknagger blir tagger på YouTube og tekst andre steder.

Opprett et videoinnlegg og legg det i køen
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

Felter

FeltHva det gjør
kindtext, image eller video. Påkrevd.
titleBrukes av plattformer med et tittelfelt: YouTube, TikTok-bildeinnlegg og Facebook-videoer.
descriptionBildeteksten, beskrivelsen eller innleggsteksten. Godtas også som body, caption eller text.
hashtagsEn liste, med eller uten #.
media_id, media_urlEn opplastet medie-ID eller en offentlig URL som Amaposta laster ned for deg. Påkrevd for bilde- og videoinnlegg.
cover_media_id, cover_urlEt forsidebilde for videoer, der plattformen støtter det.
channelsKanal-ID-er å publisere til. Utelat feltet for å bruke alle aktive kanaler i prosjektet som støtter denne innleggstypen.
overridesEndringer per kanal, med kanal-ID som nøkkel: title, description, hashtags og plattformens options, som YouTubes privacy.
schedulemode er at (med et ISO 8601-at), now eller queue for neste ledige publiseringstidspunkt. Utelat feltet for å opprette et utkast.
external_refDin egen referanse, som returneres på innlegget og i leveringer til egne API-er.
metadataJSON med valgfri struktur lagret med innlegget. Ta med "pipeline" for å merke generert innhold. Kontrollpanelet viser det, og webhooks rapporterer opprinnelsen som pipeline.

Svaret er innlegget, med én oppføring i deliveries per kanal.

Trygge nye forsøk

Nettverk kan miste forespørsler. Send en Idempotency-Key-header når du oppretter et innlegg, så vil et nytt forsøk med samme nøkkel returnere innlegget fra første forsøk i stedet for å opprette et nytt. Bruk noe stabilt fra din side, som en jobb- eller episode-ID. Nøkler kuttes til 200 tegn.

Planlegg og publiser

Planlegg et utkast, publiser det nå, legg det i køen eller fjern det fra kalenderen med POST /api/v1/posts/{post_id}/schedule.

Planlegg til et tidspunkt
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"}'
  • atPubliserer til det oppgitte tidspunktet, opptil to år frem i tid.
  • nowPubliserer med en gang.
  • queueTar neste ledige publiseringstidspunkt for innleggets kanaler i løpet av de neste 12 ukene.
  • unscheduleFlytter innlegget tilbake til utkast.

Før noe planlegges, kjøres de samme kontrollene som i innleggsredigeringen. Hvis en mislykkes, returnerer forespørselen 400 med en melding som Rett dette før planlegging: YouTube trenger en tittel. Planlegging krever tilgangsomfanget posts:publish, eller et prosjekt med godkjenninger slått på. I så fall venter innlegget i gjennomgangsinnboksen.

Les innlegg og leveringer

List opp innleggene i et prosjekt, filtrert etter status (kommaseparerte statuser eller inbox, queue eller history), et from/to-tidsrom, limit og offset. Svaret er {"items": […], "total": n}.

Hva som kommer, og ett innlegg 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"

Et innlegg har en samlet status (draft, in_review, changes_requested, ready, scheduled, publishing, published, partial eller failed) og én levering 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
  }
]

Leveringsstatusene er pending, scheduled, publishing, processing, published, failed og cancelled. DELETE /api/v1/posts/{post_id} fjerner et innlegg.

Feil

Alle feil har samme struktur: et error-objekt med en stabil code, en message du kan vise til brukere, og noen ganger fields (meldinger per felt) og et hint.

422 Unprocessable Entity
{
  "error": {
    "code": "validation",
    "message": "Please fix the highlighted fields.",
    "fields": {
      "kind": "Use text, image or video."
    }
  }
}
StatusKodeBetydning
400bad_requestForespørselen kan ikke utføres som angitt, for eksempel planlegging av et innlegg som ikke består kontrollene.
401unauthorizedAPI-nøkkelen mangler, er feil eller er tilbakekalt.
402plan_limitArbeidsområdets abonnement tillater ikke dette. limit angir hvilken grense.
403forbiddenNøkkelen mangler et tilgangsomfang eller tilgang til prosjektet.
404not_foundProsjektet, innlegget, mediefilen eller endepunktet finnes ikke.
409conflictEndringen er i konflikt med gjeldende tilstand, for eksempel redigering av et innlegg som allerede publiseres.
422validationEtt eller flere felt må rettes. Se fields.
429rate_limitedMer enn 120 forespørsler i minuttet med denne nøkkelen.
502provider_errorEn plattform avviste forespørselen eller feilet. hint forteller hva du bør gjøre.

Webhooks

Legg til et endepunkt under Innstillinger, API og webhooks, velg ønskede hendelser og kopier signeringshemmeligheten. Amaposta sender JSON med POST til URL-en din for hver hendelse. Alt annet enn et 2xx-svar, eller manglende svar innen 15 sekunder, prøves på nytt med økende ventetid. Endepunkter som fortsetter å feile, slås av med et varsel til administratorer.

HendelseSendes når
post.createdEt innlegg ble opprettet (kontrollpanel eller API)
post.scheduledEt innlegg ble planlagt
post.approvedEt innlegg ble godkjent
post.publishedEt innlegg ble publisert på en kanal
post.failedEt innlegg kunne ikke publiseres på en kanal
channel.connectedEn kanal ble koblet til eller koblet til på nytt
channel.disconnectedEn kanal mistet tilkoblingen
media.readyEn opplasting ble ferdig behandlet
media.failedEn opplasting kunne ikke behandles
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=…"
  }
}

Kontroller signaturen

X-Amaposta-Signature er t=<unix seconds>,v1=<hex>, der v1 er HMAC_SHA256(secret, t + "." + body) over den rå forespørselskroppen. Beregn den selv, sammenlign i konstant tid, og avvis gamle tidsstempler for å hindre gjenavspilling.

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

Egne API-kanaler

En egen API-kanal publiserer til et HTTPS-endepunkt du drifter: CMS-et ditt, et nyhetsbrevverktøy eller en plattform Amaposta ennå ikke dekker. Den vises i kalenderen og får kontroller, godkjenninger og nye forsøk som alle andre kanaler. Når et innlegg sendes ut, sender Amaposta én POST per levering:

Hva endepunktet ditt mottar
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" }
}

Hvordan svare

  • 2xxPublisert. Returner eventuelt {"id": "…", "url": "…"}, så vises lenken på innlegget.
  • 401, 403Nøkkelen ble avvist. Kanalen merkes for ny tilkobling, og administratorer varsles. Ikke bruk disse ved ugyldig signatur.
  • 5xx, 408, 429Midlertidig. Amaposta prøver igjen med økende ventetid.
  • Andre 4xxInnlegget merkes som mislykket med meldingen din, og noen kan rette det og trykke Prøv igjen.
En mottaker 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 });
});

Endepunktet ditt må være tilgjengelig fra internett. Omdirigeringer følges ikke. Når du kobler til kanalen, kontrollerer Amaposta den med en GET til helsesjekk-URL-en hvis du angir en, eller en OPTIONS-forespørsel til endepunktet.

Sandbox-kanaler

En Sandbox-kanal oppfører seg som en ekte kanal, men ingenting forlater Amaposta. Bruk den til å bygge og teste integrasjonen fra ende til ende: innlegg planlegges, går på lufta, publiseres eller mislykkes og utløser de samme webhookene. Sandbox-kanaler er gratis i alle abonnementer og teller ikke mot kanalgrenser.

Velg hvordan den skal oppføre seg når du legger den til:

  • Alltid vellykketAlle innlegg publiseres.
  • Mislykkes av og tilSe feil og nye forsøk uten å vente på et ekte driftsavbrudd.
  • Mislykkes alltidTest håndteringen av post.failed.
  • Utløpt tilkoblingSe hvordan varsler og lenker for ny tilkobling ser ut når tilgangen utløper.

Plattformregler

Hva hver kanaltype godtar. Kontrollene bruker de samme grensene, så de fleste problemer vises før et innlegg planlegges, i stedet for når det publiseres.

Plattform Innlegg Tittel Tekst Emneknagger Medier
YouTube Video TittelPåkrevd, opptil 100 tegn BeskrivelseOpptil 5 000 tegn Sendes som tagger, opptil 60 MP4, MOV, WebM, AVI, MKV; opptil 256 GB; 1 s til 12 t
Kontoer som ikke har bekreftet et telefonnummer, kan laste opp opptil 15 minutter og kan ikke angi egne miniatyrbilder. Hver opplasting bruker API-kvote. Googles standardkvote tillater omtrent seks opplastinger per dag per app.
Instagram Bilde Ingen tittel BildetekstOpptil 2 200 tegn Legges til i teksten, opptil 30 JPEG; opptil 8 MB
Video Ingen tittel BildetekstOpptil 2 200 tegn Legges til i teksten, opptil 30 MP4, MOV; opptil 300 MB; 3 s til 15 min
Krever en Instagram-bedriftskonto eller skaperkonto. Instagram tillater 50 innlegg publisert via API per konto i en løpende periode på 24 timer. Rene tekstinnlegg er ikke mulig på Instagram.
TikTok Bilde TittelOpptil 90 tegn BeskrivelseOpptil 4 000 tegn Legges til i teksten JPEG, WebP; opptil 20 MB
Video Ingen tittel BildetekstOpptil 2 200 tegn Legges til i teksten MP4, MOV, WebM; opptil 4 GB; 3 s til 10 min
Innlegg fra apper som ikke har fullført TikToks kontroll, er bare synlige for skaperen. TikTok velger forsiden fra et videobilde. Egne forsidebilder støttes ikke. Rene tekstinnlegg er ikke mulig på TikTok.
X Tekst Ingen tittel InnleggPåkrevd, opptil 280 (lenker teller som 23, emojier som 2) Legges til i teksten Ingen
Bilde Ingen tittel InnleggOpptil 280 (lenker teller som 23, emojier som 2) Legges til i teksten JPEG, PNG, WebP, GIF; opptil 5 MB
Video Ingen tittel InnleggOpptil 280 (lenker teller som 23, emojier som 2) Legges til i teksten MP4, MOV; opptil 512 MB; 0,5 s til 2:20 min
Med din egen X-utviklerapp bruker innlegg appens API-kreditter som betales per bruk. Emneknagger teller mot tegngrensen.
Facebook Tekst Ingen tittel InnleggPåkrevd, opptil 63 206 tegn Legges til i teksten Ingen
Bilde Ingen tittel BildetekstOpptil 63 206 tegn Legges til i teksten JPEG, PNG, GIF, WebP; opptil 10 MB
Video TittelOpptil 255 tegn BeskrivelseOpptil 63 206 tegn Legges til i teksten MP4, MOV; opptil 1 GB; 1 s til 20 min
Publiserer bare til sider. Personlige profiler kan ikke publiseres til gjennom API-et.
Eget API Tekst TittelIngen lengdegrense BeskrivelseIngen lengdegrense Sendes som tagger Ingen
Bilde TittelIngen lengdegrense BeskrivelseIngen lengdegrense Sendes som tagger JPEG, PNG, WebP, GIF
Video TittelIngen lengdegrense BeskrivelseIngen lengdegrense Sendes som tagger MP4, MOV, WebM
Hver forespørsel signeres med en HMAC-SHA256-header slik at du kan kontrollere at den kom fra Amaposta. Svar med 2xx og valgfri JSON {"id": "…", "url": "…"}. Svar med 408, 429 og 5xx prøves på nytt med økende ventetid. 401/403 merker kanalen for ny tilkobling. Andre 4xx markerer leveringen som mislykket, slik at du kan rette den og prøve igjen.
Sandbox Tekst TittelOpptil 200 tegn BeskrivelseOpptil 5 000 tegn Legges til i teksten, opptil 30 Ingen
Bilde TittelOpptil 200 tegn BeskrivelseOpptil 5 000 tegn Legges til i teksten, opptil 30 JPEG, PNG, WebP, GIF
Video TittelOpptil 200 tegn BeskrivelseOpptil 5 000 tegn Legges til i teksten, opptil 30 MP4, MOV, WebM
Publisering tar et øyeblikk slik at du kan se statusen endre seg direkte.