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.
| Formaat | Ondersteund | Opmerkingen uit de documentatie |
|---|---|---|
| Losse afbeelding | Ja | JPEG, meegegeven als publieke image_url |
| Video / Reels | Ja | media_type=REELS met video_url |
| Stories | Ja | media_type=STORIES |
| Carrousel | Ja | Tot 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?
- Upload je media ergens publiek bereikbaar. Meta haalt het op via URL, dus een getekende URL die na 60 seconden verloopt, zal falen.
POST /<IG_ID>/mediametimage_urlofvideo_url,caption, enmedia_typeals het geen gewone afbeelding is. Je krijgt een container-ID terug.- Poll
GET /<IG_CONTAINER_ID>?fields=status_codetotdat hetFINISHEDaangeeft. Meta raadt aan om eens per minuut te pollen, niet langer dan vijf minuten. POST /<IG_ID>/media_publishmetcreation_idingesteld op het container-ID.- 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. Pollstatus_codedaartussen. - 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/.