Instagram API

How to post on Instagram
with an API

Schedule feed posts and Reels on Instagram from code. Connect the account and create the post with media.

the whole flow

Four steps, then it is scheduled

You call PostWing. PostWing publishes to Instagram at the time you set. The post also shows up on your calendar.

  1. 01Create an API key
  2. 02Connect Instagram
  3. 03Create the post
  4. 04Cross-post to more channels
01

Create an API key

Open Dashboard → AI & API and create a key. Copy it once. It starts with pw_live_. Send it on every request:

Header

Authorization: Bearer pw_live_…

Every URL below starts at https://postwing.io/api/v2.

02

Connect Instagram

Connect the Instagram account you want to post from. You only do this once.

The simple way is in the dashboard. Open Accounts, choose Instagram, and finish the Instagram login.

From the API, start that same login. The response includes a url. Open it and approve Instagram.

Start connect

curl -s -X POST "https://postwing.io/api/v2/accounts/connect" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "platform": "instagram" }'

After you finish in the browser, sync. This imports the account into your workspace and returns the account id.

Sync

curl -s -X POST "https://postwing.io/api/v2/accounts/sync" \
  -H "Authorization: Bearer pw_live_…"

In the response, find the object where platform is instagram and copy id. That is the id you send when you create the post.

Sync response

{
  "data": [
    {
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "platform": "instagram",
      "handle": "brand",
      "display_name": "Brand",
      "status": "connected"
    }
  ]
}

Connected Instagram in the dashboard instead? The sync response is not in front of you, so list accounts and copy the same field:

List accounts

curl -s -X GET "https://postwing.io/api/v2/accounts" \
  -H "Authorization: Bearer pw_live_…"
03

Create the post

Send the caption, a future time, and the Instagram account id you copied after sync. Instagram needs an image or a video, so this example includes one image. This call schedules the post. Instagram publishes it at scheduled_at. scheduled_at is UTC. The image URL has to be public HTTPS.

Create a feed post

curl -s -X POST "https://postwing.io/api/v2/posts" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "caption": "New hours this week. We are open until 7.",
  "scheduled_at": "2026-10-12T15:00:00Z",
  "accounts": [
    { "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901" }
  ],
  "media": [
    { "url": "https://cdn.example.com/storefront.jpg", "type": "image" }
  ]
}'

One image goes to the feed. Add more images in media for a carousel, up to 10.

You get back three things that matter:

  • id: the post id, for edits or cancelling later
  • status: scheduled until it publishes
  • accounts: each account, with url once it is live and error if it fails

Response

{
  "id": "7c1d2a8e-4b0f-4f8e-9a51-2f7f6b1c9d10",
  "status": "scheduled",
  "caption": "New hours this week. We are open until 7.",
  "scheduled_at": "2026-10-12T15:00:00.000Z",
  "accounts": [
    {
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "platform": "instagram",
      "handle": "brand",
      "status": "scheduled",
      "url": null,
      "error": null
    }
  ],
  "dashboard_url": "https://postwing.io/dashboard/post/7c1d2a8e-4b0f-4f8e-9a51-2f7f6b1c9d10"
}
04

Cross-post to Facebook and TikTok

The same post can go to Facebook and TikTok. Connect each channel the way you connected Instagram, then copy its id from the sync response.

Connect Facebook

curl -s -X POST "https://postwing.io/api/v2/accounts/connect" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "platform": "facebook" }'

Connect TikTok

curl -s -X POST "https://postwing.io/api/v2/accounts/connect" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "platform": "tiktok" }'

Open each url, finish the login, then sync once. Copy id where platform is facebook, and where platform is tiktok.

Add those ids to accounts on the create call. One request. Every account publishes at the same scheduled_at. Leave caption off an account to use the shared caption. Set caption when that channel needs different text.

Create one post for three channels

curl -s -X POST "https://postwing.io/api/v2/posts" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "caption": "New hours this week. We are open until 7.",
  "scheduled_at": "2026-10-12T15:00:00Z",
  "accounts": [
    { "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901" },
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "caption": "Open until 7 this week."
    },
    { "id": "c3d4e5f6-a7b8-9012-cdef-123456789012" }
  ],
  "media": [
    { "url": "https://cdn.example.com/storefront.jpg", "type": "image" }
  ]
}'

video

Post a Reel

A video becomes a Reel. Use the same Instagram account id from sync. share_to_feed also puts that Reel on the main feed. cover.url is the cover image.

Create a Reel

curl -s -X POST "https://postwing.io/api/v2/posts" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "caption": "A 15-second look at the new menu",
  "scheduled_at": "2026-10-12T18:00:00Z",
  "accounts": [
    {
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "options": { "share_to_feed": true }
    }
  ],
  "media": [
    {
      "url": "https://cdn.example.com/reel.mp4",
      "type": "video",
      "cover": { "url": "https://cdn.example.com/cover.jpg" }
    }
  ]
}'

share_to_feed defaults to true, so the Reel also goes on the main feed. Set it to false to keep the Reel off the feed. Leave cover off to use a frame from the video.

Videos imported from a URL need to be 100MB or smaller. A file on your computer uses the direct upload URL, covered in the API docs.

trial

Post a trial Reel

A trial Reel is a video you test before everyone sees it. Use the same Instagram account id, and set trial_reel.

Create a trial Reel

curl -s -X POST "https://postwing.io/api/v2/posts" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "caption": "Testing this Reel before it reaches everyone",
  "scheduled_at": "2026-10-12T18:30:00Z",
  "accounts": [
    {
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "options": { "trial_reel": "manual" }
    }
  ],
  "media": [
    { "url": "https://cdn.example.com/reel.mp4", "type": "video" }
  ]
}'

manual means you decide when the Reel graduates. performance lets it graduate on its own if it does well.

The account needs 1,000 followers, and you can post up to 5 trial Reels a day. Leave trial_reel off for a normal Reel.

Details worth knowing

  • scheduled_at has to be a future time in ISO 8601, usually UTC.
  • POST /posts schedules the post right away. You can still edit or cancel it until it publishes.
  • Instagram needs an image or a video. A caption by itself is not enough.
  • The response includes the post id. Use it to edit with PATCH /posts/{id} or cancel with DELETE /posts/{id}.
  • API access is included on every plan, from $9.99/mo. Posts count as normal posts on your account.

questions

Instagram API FAQ

No. Instagram needs an image or a video. Create the post with caption, scheduled_at, the Instagram account id, and media.

ready when you are

Schedule your next Instagram post from the API

Create a key, connect Instagram, and create the post.