YouTube API

How to post on YouTube
via the API

Post and schedule videos on YouTube programmatically using the API. Create a key, connect YouTube, and upload the video.

the whole flow

Five steps, then it is scheduled

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

  1. 01Create an API key
  2. 02Connect YouTube
  3. 03Create the video
  4. 04Cross-post to more channels
  5. 05Confirm it
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/v1.

02

Connect YouTube

Connect the YouTube channel you want to upload to. You only do this once.

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

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

Start connect

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

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

Sync

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

In the response, find the object where platform is youtube and copy account_id. That is the id you send when you create the video.

Sync response

{
  "synced_count": 1,
  "accounts": [
    {
      "account_id": "a7b8c9d0-e1f2-3456-0123-567890123456",
      "platform": "youtube",
      "handle": "brand",
      "display_name": "Brand",
      "status": "connected"
    }
  ]
}

Connected YouTube in the dashboard instead? List accounts and copy the same field:

List accounts

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

Create the video

YouTube needs a video and a title. A caption by itself is not enough. caption is the description. title goes on the YouTube target. This call creates the video. YouTube does not publish until you confirm in the next step. scheduled_at is UTC.

Create a video

curl -s -X POST "https://postwing.io/api/v1/posts/preview" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "caption": "A walkthrough of the new publishing flow.",
  "scheduled_at": "2026-10-12T15:00:00Z",
  "targets": [
    {
      "account_id": "a7b8c9d0-e1f2-3456-0123-567890123456",
      "platform_options": {
        "title": "How we publish now",
        "made_for_kids": false
      }
    }
  ],
  "media_items": [
    { "url": "https://cdn.example.com/walkthrough.mp4", "type": "video" }
  ]
}'

You get back three things that matter:

  • preview: the description, title, time, and YouTube channel. Check this before you confirm.
  • confirmation_token: you send this in the next step
  • expires_in_seconds: 300, so the token lasts 5 minutes

Response

{
  "preview": {
    "caption": "A walkthrough of the new publishing flow.",
    "scheduled_at": "2026-10-12T15:00:00.000Z",
    "post_type": "video",
    "targets": [
      {
        "account_id": "a7b8c9d0-e1f2-3456-0123-567890123456",
        "platform": "youtube",
        "handle": "brand"
      }
    ]
  },
  "confirmation_token": "eyJ…signature",
  "expires_in_seconds": 300
}

One video per post. The video URL has to be public HTTPS, and videos imported from a URL need to be 100MB or smaller. A title is capped at 100 characters. The description in caption is capped at about 5,000 characters. Set made_for_kids to true only when the video is made for kids.

04

Cross-post to all 8 platforms

The same video can go to Instagram and TikTok. Connect each channel the way you connected YouTube, then copy its account_id from the sync response.

Connect Instagram

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

Connect TikTok

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

Open each url, finish the login, then sync once. Copy account_id where platform is instagram, and where platform is tiktok or tiktok_business.

Add those ids to targets on the create call. Keep title on the YouTube target only. One request, one confirm. Every account publishes at the same scheduled_at. Leave caption off a target to use the shared description. Set caption when that channel needs different text.

Create one video for three channels

curl -s -X POST "https://postwing.io/api/v1/posts/preview" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "caption": "A walkthrough of the new publishing flow.",
  "scheduled_at": "2026-10-12T15:00:00Z",
  "targets": [
    {
      "account_id": "a7b8c9d0-e1f2-3456-0123-567890123456",
      "platform_options": {
        "title": "How we publish now",
        "made_for_kids": false
      }
    },
    { "account_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901" },
    {
      "account_id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
      "caption": "New publishing flow."
    }
  ],
  "media_items": [
    { "url": "https://cdn.example.com/walkthrough.mp4", "type": "video" }
  ]
}'

Facebook, LinkedIn, X, and Threads can use this video too. Pinterest needs board_ids on its own target. YouTube still needs its title.

05

Confirm the video

When the YouTube preview looks right, confirm with the token from that response. Use the token as-is. Do not invent one.

Confirm

curl -s -X POST "https://postwing.io/api/v1/posts/confirm" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{ "confirmation_token": "eyJ…signature" }'

The response includes view_url. Open it to see the video on your calendar. YouTube publishes at the time you set. Instagram and TikTok publish then too, when you added them. You can edit or cancel later from the dashboard or with the same API.

If confirm says the token expired, create the video again and confirm the new token within 5 minutes.

cover

Set a custom cover

thumbnail_url is the cover image. Put it on the video. Leave it off to use a frame from the file.

Create a video with a cover

curl -s -X POST "https://postwing.io/api/v1/posts/preview" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "caption": "A walkthrough of the new publishing flow.",
  "scheduled_at": "2026-10-12T15:00:00Z",
  "targets": [
    {
      "account_id": "a7b8c9d0-e1f2-3456-0123-567890123456",
      "platform_options": {
        "title": "How we publish now",
        "made_for_kids": false
      }
    }
  ],
  "media_items": [
    {
      "url": "https://cdn.example.com/walkthrough.mp4",
      "type": "video",
      "thumbnail_url": "https://cdn.example.com/cover.jpg"
    }
  ]
}'

The cover URL has to be public HTTPS. Leave thumbnail_url off and set thumbnail_timestamp_ms when you want a frame from the video. The default frame is 1000 milliseconds, the first second.

A file on your computer uses the direct upload URL, covered in the API docs.

shorts

Post a Short

A Short is the same request. Send a short vertical video. There is no separate Shorts field. You still send a title.

Create a Short

curl -s -X POST "https://postwing.io/api/v1/posts/preview" \
  -H "Authorization: Bearer pw_live_…" \
  -H "Content-Type: application/json" \
  -d '{
  "caption": "The 20-second version.",
  "scheduled_at": "2026-10-12T18:00:00Z",
  "targets": [
    {
      "account_id": "a7b8c9d0-e1f2-3456-0123-567890123456",
      "platform_options": {
        "title": "How we publish now",
        "made_for_kids": false
      }
    }
  ],
  "media_items": [
    { "url": "https://cdn.example.com/short.mp4", "type": "video" }
  ]
}'

YouTube treats a short vertical video as a Short. A longer video stays a regular upload. The title is still required either way.

Details worth knowing

  • scheduled_at has to be a future time in ISO 8601, usually UTC.
  • Creating the video does not publish it. Confirm is the step that schedules it.
  • YouTube needs a video and a title. A caption by itself is not enough. caption is the description.
  • made_for_kids defaults to false. Set it to true only when the video is made for kids.
  • A title is capped at 100 characters. The description is capped at about 5,000 characters.
  • A short vertical video can publish as a Short. There is no separate Shorts field.
  • The confirmation token expires in 5 minutes and only works for the user who created the video.
  • API access is included on every plan, from $9.99/mo. Videos count as normal posts on your account.

questions

YouTube API FAQ

No. YouTube needs a video in media_items and a title on targets[].platform_options. caption is the description. Then confirm with the token.

ready when you are

Schedule your next YouTube video from the API

Create a key, connect YouTube, and upload the video.