How to Upload to YouTube via API
The request flow for uploading and publishing video to YouTube programmatically.
Uploading to YouTube via API takes five steps: connect the channel through hosted OAuth, get the video to PostGate (pre-upload to POST /api/media for anything beyond a short clip), create the post with the YouTube fields the platform requires — title, privacy status, and the made-for-kids declaration — then track the target through processing and handle quota and audience-declaration errors.
Uploading a video to YouTube programmatically is five steps: authorize the channel, get the video file somewhere the API can read it, submit the upload with required metadata, track the target through processing, and handle the errors that are specific to YouTube — quota, audience declaration, and channel-level restrictions. This walks through each step using PostGate's API, and calls out where the raw YouTube Data API v3 flow differs.
1. Connect the channel
Before anything can be uploaded, the channel needs to be connected through OAuth. PostGate hosts the consent screen and token exchange so your product only handles a return URL, not YouTube's OAuth app review process directly.
curl -X POST https://postgate.studio/api/profiles/connect \
-H "Authorization: Bearer $POSTGATE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"platform": "youtube",
"profile_group_id": "grp_acme123",
"return_url": "https://app.example.com/settings/social"
}'2. Get the video into PostGate
You can hand PostGate a public URL, a base64 data URL, or pre-upload the file to POST /api/media and reuse the returned media ID. For anything beyond a short clip, pre-uploading is the right call — it validates the file before you spend a request creating the post, and it is what backs the resumable protocol required for large video files. See YouTube Resumable Upload API for why that matters specifically for video.
curl -X POST https://postgate.studio/api/media \
-H "Authorization: Bearer $POSTGATE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source": "upload",
"filename": "launch-story.mp4",
"mime": "video/mp4",
"bytes": 314572800
}'3. Create the post with YouTube options
Attach the media ID, the connected YouTube profile, and the platform-specific fields YouTube requires — title, privacy status, and the made-for-kids declaration — under post.options.youtube. A stable Idempotency-Key means a client-side retry after a timeout never produces a duplicate upload.
curl -X POST "https://postgate.studio/api/posts?profile_group_id=grp_acme123" \
-H "Authorization: Bearer $POSTGATE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: yt-launch-001" \
-d '{
"post": {
"body": "Launch day.",
"options": {
"youtube": {
"title": "Launch story",
"privacy": "private",
"made_for_kids": false,
"community_guidelines_confirmed": true
}
}
},
"profiles": ["pro_youtube123"],
"media": ["med_01JXYZ"]
}'4. Track the target through processing
The response confirms the post was accepted, not that YouTube has finished processing the video. Read GET /api/posts/{id} for the target's current status, or — better for production — subscribe to post.published, post.partial, and post.failed webhooks instead of polling. See Delivery lifecycle for the full status model and Automate YouTube Uploads for the event-driven pattern.
5. Handle the errors YouTube actually returns
Two failure modes are specific to YouTube and worth checking for explicitly: quota exhaustion (the upload allowance is separate from most other API activity, so it can fail even when your project looks healthy overall) and missing or invalid audience declarations. PostGate surfaces both as structured, platform-tagged errors rather than a generic failure — see Fixing YouTube API 403 quotaExceeded for the quota model in detail, and Errors & retries for the envelope shape.
Frequently asked questions
What metadata does YouTube require when uploading via API?
Title, privacy status, and the made-for-kids audience declaration, passed under post.options.youtube. A missing or invalid audience declaration is one of the two failure modes specific to YouTube worth checking for explicitly.
Should I pre-upload the video file before creating a YouTube post?
For anything beyond a short clip, yes. Pre-uploading to POST /api/media validates the file before you spend a request creating the post, and it is what backs the resumable protocol required for large video files. Alternatively, you can hand PostGate a public URL or a base64 data URL.
Why did my YouTube upload fail with a quota error?
YouTube’s upload allowance is separate from most other API activity, so an upload can fail on quota exhaustion even when your project looks healthy overall. PostGate surfaces it as a structured, platform-tagged error rather than a generic failure.
How do I avoid duplicate YouTube uploads on retry?
Send a stable Idempotency-Key with the create request. A client-side retry after a timeout then never produces a duplicate upload.
How do I know when YouTube has finished processing the video?
The create response confirms the post was accepted, not that YouTube has finished processing. Read GET /api/posts/{id} for the target’s current status, or — better for production — subscribe to the post.published, post.partial, and post.failed webhooks instead of polling.
