Instagram API Post Tutorial: Publiceren met de Graph API

Instagram API Post Tutorial: Publiceren met de Graph API

Hoe je publiceert naar Instagram via de API: de containerflow in twee stappen, de accountvereisten, de dagelijkse limiet van 100 posts, en wat echt tijd kost.

Publiceren naar Instagram via de API is een aanroep in twee stappen: maak een mediacontainer met POST /<IG_ID>/media, en publiceer die dan met POST /<IG_ID>/media_publish. De lastige onderdelen zijn niet de aanroepen. Het zijn de accountvereisten, de app-review van Meta, en het feit dat een 200-respons van de containerstap niet betekent dat er al iets live staat.

Dit is geschreven voor een developer die overweegt dit intern te bouwen.

Wat kan de Instagram API eigenlijk publiceren?

De Content Publishing-documentatie van Meta noemt vier media_type-waarden voor containers: VIDEO, REELS, STORIES en CAROUSEL. Een gewone losse afbeelding is de standaard wanneer je image_url meegeeft zonder media_type.

FormaatOndersteundOpmerkingen uit de documentatie
Losse afbeeldingJaJPEG, meegegeven als publieke image_url
Video / ReelsJamedia_type=REELS met video_url
StoriesJamedia_type=STORIES
CarrouselJaTot 10 afbeeldingen, video’s of een mix

Twee dingen verrassen mensen. Ten eerste: Stories zijn publiceerbaar, maar als je een gepubliceerde story terugleest, geeft media_type IMAGE of VIDEO terug, dus je moet media_product_type opvragen om te weten wat het echt is. Ten tweede: carrouselafbeeldingen worden allemaal bijgesneden op de eerste afbeelding, standaard op 1:1, dus je bijsnijdbeslissingen worden voor je gemaakt.

Het gat dat het meest telt, is geen formaat. Het is het account. Publiceren vereist een professioneel Instagram-account (Business of Creator) gekoppeld aan een Facebook-pagina, met instagram_basic, instagram_content_publish en pages_read_engagement toegekend. Een persoonlijk Instagram-account kan via de API helemaal niet worden gepubliceerd, ongeacht wat je code doet. Als je gebruikers creators zijn met persoonlijke accounts, is de integratie dood voordat je een regel code schrijft.

Let op: Cijfers hier zijn geverifieerd aan de hand van de Instagram Platform Content Publishing-documentatie van Meta vanaf september 2026. Platforms wijzigen dit zonder aankondiging.

Hoe werkt authenticatie, en hoe lang duurt app-review?

Je krijgt een gebruikerstoegangstoken via Facebook Login, en wisselt dan het kortlevende token server-side in voor een langlevend token via GET oauth/access_token met grant_type=fb_exchange_token. Meta documenteert dat het langlevende gebruikerstoken ongeveer 60 dagen meegaat. De automatische vernieuwing die Meta beschrijft, geldt voor SDK-beheerde tokens, dus als je zelf tokens inwisselt, heb je vóór dag 60 je eigen vernieuwings- of herauthenticatiepad nodig.

App-review is vereist voor de publiceerrechten voordat iemand buiten je eigen app-rollen de integratie kan gebruiken. Meta publiceert geen gegarandeerde doorlooptijd voor review in deze developerdocumentatie, dus behandel de duur als onbekend en houd rekening met minstens één afwijzingsronde. Screencasts maken deel uit van de indiening, wat betekent dat je een werkende demo nodig hebt voordat je goedkeuring krijgt, op een app die nog geen echte gebruikers mag bedienen.

Wat is de volgorde van publicatieaanroepen?

  1. Upload je media ergens publiek bereikbaar. Meta haalt het op via URL, dus een getekende URL die na 60 seconden verloopt, zal falen.
  2. POST /<IG_ID>/media met image_url of video_url, caption, en media_type als het geen gewone afbeelding is. Je krijgt een container-ID terug.
  3. Poll GET /<IG_CONTAINER_ID>?fields=status_code totdat het FINISHED aangeeft. Meta raadt aan om eens per minuut te pollen, niet langer dan vijf minuten.
  4. POST /<IG_ID>/media_publish met creation_id ingesteld op het container-ID.
  5. Sla het geretourneerde media-ID op. Dat, niet het container-ID, is de gepubliceerde post.
# 1. create the container
curl -X POST "https://graph.facebook.com/v23.0/$IG_ID/media" \
  -d "image_url=https://example.com/photo.jpg" \
  -d "caption=Ship it." \
  -d "access_token=$TOKEN"
# -> {"id":"17889455560051444"}

# 2. poll until FINISHED
curl "https://graph.facebook.com/v23.0/17889455560051444?fields=status_code&access_token=$TOKEN"

# 3. publish
curl -X POST "https://graph.facebook.com/v23.0/$IG_ID/media_publish" \
  -d "creation_id=17889455560051444" -d "access_token=$TOKEN"

Container status_code kan zijn: IN_PROGRESS, FINISHED, ERROR, EXPIRED of PUBLISHED. EXPIRED betekent dat de container niet binnen 24 uur is gepubliceerd. Voor een carrousel maak je één container per item met is_carousel_item=true, en dan een oudercontainer met media_type=CAROUSEL en een door komma’s gescheiden children-lijst.

Wat zijn de ratelimieten?

De gedocumenteerde publicatielimiet is direct: Instagram-accounts zijn beperkt tot 100 via de API gepubliceerde posts binnen een voortschrijdende periode van 24 uur, en een carrousel telt als één post. Je kunt het huidige gebruik uitlezen via GET /<IG_ID>/content_publishing_limit in plaats van te gokken, en dat is wat je moet doen voordat je een bulkrun start.

Dat is een voortschrijdend venster, geen kalenderdag. Als je om 15:00 uur 100 posts hebt verbruikt, krijg je om middernacht geen nieuw budget. Elke wachtrij die je bouwt, moet het venster modelleren, niet een dagelijkse teller.

Let op: Cijfers hier zijn geverifieerd aan de hand van de Instagram Platform Content Publishing-documentatie van Meta vanaf september 2026. Platforms wijzigen dit zonder aankondiging.

Wat kost je echt drie weken?

Niet de twee API-aanroepen. Deze vier dingen:

App-review. Je kunt niet live gaan tot Meta instagram_content_publish goedkeurt, en je kunt geen nette demo geven voordat je het ding hebt gebouwd. Houd rekening met opnieuw indienen.

Tokenvernieuwing. Langlevende tokens van zestig dagen betekenen een achtergrondtaak, een foutstatus in je UI voor “dit account moet opnieuw worden gekoppeld”, en e-mail naar de gebruiker voordat het token verloopt, niet erna. Sla dit over en elke integratie stopt stilletjes twee maanden na lancering.

Mediahosting en formaatbeperkingen. Meta haalt media op via jouw URL. Dat betekent publieke hosting, correcte content-types, en transcoderen naar wat Instagram accepteert. Losse afbeeldingen zijn JPEG. Video moet de eigen verwerkingsstap van Instagram overleven, die plaatsvindt nadat je aanroep terugkeert.

Asynchrone foutafhandeling. Een 200 op de containeraanroep betekent dat Meta een taak heeft geaccepteerd. De post kan nog steeds mislukken tijdens verwerking, en je komt dat alleen te weten door status_code te pollen en ERROR te zien. Als je datamodel alleen “gepubliceerd” en “mislukt” kent, rapporteer je succes voor posts die nooit zijn verschenen. Modelleer een processing-status en een echte eindcheck, zoals behandeld in onze gids over de social media inplan-API.

Vermenigvuldig dat vervolgens. Reels en Stories hebben hun eigen eigenaardigheden, en als je ook TikTok of LinkedIn wilt, begin je opnieuw met een ander authenticatiemodel, een andere uploadflow en een ander reviewproces.

De korte versie

  • Twee aanroepen: maak container, dan media_publish. Poll status_code daartussen.
  • Vereist een professioneel Instagram-account gekoppeld aan een Facebook-pagina.
  • 100 via de API gepubliceerde posts per voortschrijdende 24 uur; controleer content_publishing_limit.
  • Langlevende tokens gaan ongeveer 60 dagen mee. Bouw vernieuwing vóór lancering.
  • App-review is verplicht en de duur ervan staat niet in de documentatie.

Als je captions schrijft terwijl je bouwt, laat de gratis Instagram-tekenteller zien waar afkapping plaatsvindt.

Dit één keer doen in plaats van per platform

Het alternatief voor dit per netwerk schrijven, is één API die al de tokens, de containers, het pollen en de retries bevat. BulkPublish publiceert naar 15 platforms via één REST API en SDK, dus een Instagram-post en een LinkedIn-post zijn dezelfde aanroep met een ander kanaal-ID. Tokenvernieuwing, de voortschrijdende-vensterlimiet en de asynchrone statuscontrole worden aan onze kant afgehandeld, en een post die op één platform mislukt, wordt gerapporteerd als partial in plaats van een vals succes. De referentie staat op /nl/developers/ en de REST-integratiepagina staat op /nl/integrations/rest-api/.

Gerelateerd