Creating a container is not publishing
Publishing through Instagram's API takes two calls. The first, POST /<IG_ID>/media, creates a media container for the image, video, or carousel and returns a container ID. The second, POST /<IG_ID>/media_publish with creation_id set to that ID, turns the container into a post and returns the published media ID. A tool can finish the first call and fail, time out, or stop before the second, which is why a post can look uploaded in the tool and still be missing from the profile.
Instagram processes the media between those two calls, and videos take longer than images. Meta's guide says that if you can create a container for a video but media_publish does not return a published media ID, the next step is to query the container's status rather than to start over.
Match the status code to the next action
Request the container with GET /<IG_CONTAINER_ID>?fields=status_code,status. The status_code field has five documented values. When it is ERROR, the status field carries an error subcode that says what went wrong, so request both fields together.
| status_code | What Meta's documentation says | What to do |
|---|---|---|
| IN_PROGRESS | The container is still in the publishing process | Wait and check again; Meta recommends once per minute for no more than 5 minutes |
| FINISHED | The container and its media object are ready to be published | Call media_publish with this container ID |
| ERROR | The container failed to complete the publishing process | Read the subcode in status, fix the media, and create a new container |
| EXPIRED | The container was not published within 24 hours | Create a new container; this one cannot be published |
| PUBLISHED | The container's media object has been published | Find the post on the profile; do not publish again |
Errors from the publish call
Some problems only show up when media_publish is called. Meta's error code reference lists the ones most often confused with a stuck container. Subcode 2207027, "The media is not ready for publishing, please wait for a moment", means the container was not FINISHED yet: check the status and publish once it is. Subcode 2207008 says the media builder for the creation ID does not exist or has expired; Meta calls this a temporary error and suggests trying again once or twice over the next 30 seconds to 2 minutes, then creating a new container if it still fails. Subcode 2207020 says the media has expired, and the only fix is a new container.
Two other errors are not about the container at all. Subcode 2207042 means the account reached the maximum number of posts the Content Publishing API allows, and Meta's advice is to try again the next day. Subcode 2207026 means the video format is not supported, and Meta asks for MOV or MP4 (MPEG-4 Part 14). Retrying either one unchanged will fail the same way.
Check the publishing limit before a batch
Meta's content publishing guide says Instagram accounts are limited to 100 API-published posts in a 24-hour moving period, that a carousel counts as a single post, and that the limit is enforced when media_publish is called, not when a container is created. The same page also mentions a 50-post limit in its carousel section, so treat the number as something to check rather than to remember: GET /<IG_ID>/content_publishing_limit returns the account's current usage.
This matters when you clear a backlog. Containers can be created freely, then pile up unpublished once the limit is reached, and every one of them expires 24 hours after it was made. Publish in smaller batches and check usage first instead of preparing a day's worth of containers at once.
- Read status_code and status for the container ID your tool recorded.
- If it is PUBLISHED, open the profile and confirm the post before doing anything else.
- If it is IN_PROGRESS, wait and check again for a few minutes before you resend.
- If it is ERROR or EXPIRED, fix the cause and create a new container from the same media.
- Before a large batch, check content_publishing_limit so the containers do not expire waiting for room.
Illustrative example: a Reel that never appeared
This example is illustrative, not a customer case. A creator schedules a two-minute Reel for 9:00. The tool creates the container at 9:00 and checks the status a few times, but the video is still IN_PROGRESS when the tool stops waiting, so nothing is published. At 9:20 the container reports FINISHED. Publishing it then works, because it is well within 24 hours, and gives the creator the original post instead of a second upload. If nobody looks until the next morning, the container is EXPIRED and the only route is a new container from the original file.
The useful habit is to keep the container ID next to the scheduled post. With it, any of the five states leads to one clear action; without it, the only option left is to upload again and hope the first attempt did not publish.
How this works in Ferryman
Ferryman uses this two-step flow for Instagram images, carousels, stories, and Reels. After creating a container it checks the status every few seconds and calls media_publish as soon as Instagram reports FINISHED; for videos it keeps checking for about four minutes. If Instagram reports ERROR, Ferryman stops and records Instagram's message as that destination's failure reason. If processing does not finish in time, the Instagram destination is reported as failed with a processing timeout rather than being published later. If media_publish answers that the media is not ready yet, Ferryman waits and tries the publish call again a few times before reporting a failure. Other destinations in the same post are not affected; see the partial-failure checklist for recovering one failed destination without duplicating the rest.
Sources & further reading
Written by Ferryman. Sources checked Oct 23, 2026. Platform rules can change; consult the linked documentation for current requirements.