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.
the whole flow
You call PostWing. PostWing publishes to YouTube at the time you set. The post also shows up on your calendar.
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.
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/v2/accounts/connect" \
-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/v2/accounts/sync" \ -H "Authorization: Bearer pw_live_…"
In the response, find the object where platform is youtube and copy id. That is the id you send when you create the video.
Sync response
{
"data": [
{
"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/v2/accounts" \ -H "Authorization: Bearer pw_live_…"
YouTube needs a video and a title. A caption by itself is not enough. caption is the description. title goes on the YouTube account. This call schedules the video. YouTube publishes it at scheduled_at. scheduled_at is UTC.
Create a video
curl -s -X POST "https://postwing.io/api/v2/posts" \
-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",
"accounts": [
{
"id": "a7b8c9d0-e1f2-3456-0123-567890123456",
"options": {
"title": "How we publish now",
"made_for_kids": false
}
}
],
"media": [
{ "url": "https://cdn.example.com/walkthrough.mp4", "type": "video" }
]
}'You get back three things that matter:
Response
{
"id": "7c1d2a8e-4b0f-4f8e-9a51-2f7f6b1c9d10",
"status": "scheduled",
"caption": "A walkthrough of the new publishing flow.",
"scheduled_at": "2026-10-12T15:00:00.000Z",
"accounts": [
{
"id": "a7b8c9d0-e1f2-3456-0123-567890123456",
"platform": "youtube",
"handle": "brand",
"status": "scheduled",
"url": null,
"error": null
}
],
"dashboard_url": "https://postwing.io/dashboard/post/7c1d2a8e-4b0f-4f8e-9a51-2f7f6b1c9d10"
}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.
The same video can go to Instagram and TikTok. Connect each channel the way you connected YouTube, then copy its id from the sync response.
Connect Instagram
curl -s -X POST "https://postwing.io/api/v2/accounts/connect" \
-H "Authorization: Bearer pw_live_…" \
-H "Content-Type: application/json" \
-d '{ "platform": "instagram" }'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 instagram, and where platform is tiktok.
Add those ids to accounts on the create call. Keep title on the YouTube account only. One request. Every account publishes at the same scheduled_at. Leave caption off an account 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/v2/posts" \
-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",
"accounts": [
{
"id": "a7b8c9d0-e1f2-3456-0123-567890123456",
"options": {
"title": "How we publish now",
"made_for_kids": false
}
},
{ "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901" },
{
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"caption": "New publishing flow."
}
],
"media": [
{ "url": "https://cdn.example.com/walkthrough.mp4", "type": "video" }
]
}'Facebook, LinkedIn, X, and Threads can use this video too. Pinterest needs board_id in its own options. YouTube still needs its title.
cover
cover.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/v2/posts" \
-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",
"accounts": [
{
"id": "a7b8c9d0-e1f2-3456-0123-567890123456",
"options": {
"title": "How we publish now",
"made_for_kids": false
}
}
],
"media": [
{
"url": "https://cdn.example.com/walkthrough.mp4",
"type": "video",
"cover": { "url": "https://cdn.example.com/cover.jpg" }
}
]
}'The cover URL has to be public HTTPS. Leave cover off and set cover.at_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
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/v2/posts" \
-H "Authorization: Bearer pw_live_…" \
-H "Content-Type: application/json" \
-d '{
"caption": "The 20-second version.",
"scheduled_at": "2026-10-12T18:00:00Z",
"accounts": [
{
"id": "a7b8c9d0-e1f2-3456-0123-567890123456",
"options": {
"title": "How we publish now",
"made_for_kids": false
}
}
],
"media": [
{ "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.
questions
No. YouTube needs a video in media and a title on accounts[].options. caption is the description.