1. Overview
A YouTube post uploads 1 video to 1 connected YouTube channel and sets its metadata: title, description, visibility, tags, and category. YouTube is the only platform where you can edit a published post’s metadata through SocialAPI, and it has 2 ways to schedule. For everything outside publishing, see the YouTube API page.2. Supported media
- One video. A post takes exactly 1 video. Images are not accepted: an image fails pre-publish validation with
400 publishing.validation_failed, and so does a second media item. Images appear only as thumbnails when you retrieve posts. - Title. A title is required and holds up to 100 characters. SocialAPI does not check the length: YouTube refuses a longer title and the target fails with
platform.youtube.api_error. - Description.
textbecomes the description and holds up to 5,000 bytes. A longertextfails pre-publish validation with400 publishing.validation_failed. - Media sources. Use a
media_id(a file in your media library) or a publichttp(s)urlthat SocialAPI fetches when it uploads. There is novideo_urlfield. Amedia_idmust beready: a file you uploaded with the presigned flow stayspendinguntil you callPOST /v1/media/{id}/verify. Aplatform_attachment_iditem returns422 publishing.media.unsupported_source. - Unreachable files. A
urlthat does not answer fails the target withvalidation.video_url. A file whose size cannot be read fails it withvalidation.video_size.
3. Create post
SendPOST /v1/posts with a YouTube account in targets.
titleis the video title. It is required.platform_data.youtube.titleis accepted whentitleis empty, andtitlewins when both are set. SocialAPI does not derive a title from the file name or the URL.textis the video description. It is required.visibilityispublic,unlisted, orprivate. It defaults topublic, so a published video is watchable at once. Whenplatform_data.youtube.publish_atis set andvisibilityis empty, it defaults toprivate.- Without
publish_noworscheduled_at, SocialAPI saves the post as a draft.
pending to publishing, then to published or failed. Poll GET /v1/posts/{pid} or subscribe to the post.published, post.partial, and post.failed webhook events. Publishing or scheduling costs 1 post credit; a draft is free (see Plans and credits).
Where to put platform data
Pass the YouTube fields in 1 of 2 places:- Post level, keyed by platform:
platform_data.youtube. It applies to every YouTube target in the post. - Target level, flat with no
youtubekey: the target’s ownplatform_data. It applies to that target only.
category_id 22 from the post level and notify_subscribers false from the target override.
Platform data fields
SocialAPI forwards any additional keys in
platform_data.youtube only when the table above lists them. YouTube has no other publish options that SocialAPI passes through: an unlisted key is not sent.
Schedule a post
YouTube has 2 ways to schedule, and they do different things:
Use
scheduled_at to have SocialAPI do the waiting. See Scheduling.
Native scheduling
Withpublish_at, YouTube holds the uploaded video as private and makes it public at that time:
publish_at with a visibility other than private fails pre-publish validation with 400 publishing.validation_failed, with the issue on the publish_at field. An empty visibility is allowed: publish_at makes it private.
First comment
Setfirst_comment to the text of a top-level comment that SocialAPI posts on the video right after the upload. A failure to post it does not change the post: the target stays published and carries no error.
Add to playlist
Setplatform_data.youtube.playlist_id to add the video to one of your playlists after the upload. A failure here does not change the post status either.
4. Update post
Which endpoint you use depends on whether the post is published.Before publishing
PATCH /v1/posts/{pid} edits a post in draft, scheduled, or failed status. The change applies when the post publishes:
409 post.state_invalid: use the endpoint below. See Scheduling for rescheduling and the editable fields.
After publishing
PATCH /v1/platforms/youtube/accounts/{id}/videos/{videoId} edits the video on YouTube. {id} is the connected account ID and {videoId} is the YouTube video ID (platform_post_id).
- Partial edits are safe. A field you omit keeps its current value on YouTube. An omitted field is never erased.
- Tags.
tagssets the Studio tags, which are separate from any#hashtagsin the description. Editing the description does not change the tags, and setting tags does not change the description. Omittingtags, or sending an empty array, leaves the tags as they are. The API cannot clear tags. publish_at. It can be set only before the video is first published. It cannot change once the video is public.- Unknown video. A
videoIdthat does not exist on the channel returns404 resource.not_found.
5. Delete post
DELETE /v1/posts/{pid} removes the video from YouTube for every published YouTube target, and removes a draft, scheduled, or failed post from SocialAPI:
outcome is failed with the reason in message, and SocialAPI keeps the post ("deleted": false).
To remove the video from 1 channel of a multi-target post and keep the post, send POST /v1/posts/{pid}/unpublish with that target’s account_id:
6. Retrieve posts
GET /v1/posts lists posts, filtered by platform or account. It also returns videos uploaded outside SocialAPI:
platform_post_idis the YouTube video ID.metrics.likesandmetrics.commentscome from YouTube.sharesandsavesare always0: YouTube does not report them.- The view count is
metrics.extra.view_countin this list.GET /v1/posts/{pid}/metricsreads the metrics from YouTube at request time and returns the view count asmetrics.viewsandmetrics.extra.views. metrics_synced_atis on the target, not insidemetrics. It is when SocialAPI last refreshed the metrics.- Channel-level counts are on the YouTube API page.
7. Quirks, errors, and recovery
Title and description are required
A post without atitle fails its YouTube target with validation.field_required, and error.meta.field is title. A request without text returns 400 validation.field_required.
publish_at requires private visibility
YouTube schedules private videos only.publish_at with public or unlisted visibility returns 400 publishing.validation_failed before the upload starts.
First comment and playlist add never fail the post
If thefirst_comment or the playlist add fails after a successful upload, the post stays published and the failure is not reported on the post. Check the video on YouTube, or post the comment with POST /v1/inbox/comments/{postId}.
Posting caps
SocialAPI refuses a publish that would pass 25 posts in an hour or 50 posts in 24 hours for one account, with429 publishing.velocity_limit. A scheduled post is held and published when the window clears. See Posting velocity caps.
Errors on a failed target
A failed target carries anerror object:
platform.youtube.api_error: YouTube refused the request.messagecarries YouTube’s reason, for example a title over 100 characters, an unknowncategory_id, tags over YouTube’s limit, or a channel over its upload limit. Fix the request and retry.platform.youtube.rate_limit: YouTube’s own limit was reached. Wait, then retry the post.platform.youtube.auth: YouTube no longer accepts the connection. Reconnect the account.platform.youtube.insufficientPermissions: the granted scope does not permit the action. Reconnect the account to grant it again.platform.youtube.account_suspended: YouTube suspended or closed the account or its channel. Reconnecting does not help: the owner resolves it with YouTube.validation.video_url,validation.video_size,validation.field_required: the video could not be fetched, its size could not be read, or the title is missing (section 2 and above).
Recovery
- Retry a
failedorpartialpost withPOST /v1/posts/{pid}/retry. A retry costs 1 post credit. See Delivery. - After an auth error, reconnect the account, then retry.
8. Full worked example
This example uploads a video, publishes it with a title, description, tags, and a YouTube-side scheduled publish time, and checks the result. Step 1: Upload the videoupload_url, then verify it:
"status": "publishing" and the post id, as in section 3.
Step 3: Check the result
2026-10-20T10:00:00Z. If the target is failed, read targets[].error (section 7), fix the request, and call POST /v1/posts/{pid}/retry.
9. Required OAuth scopes
Publishing uses the scope SocialAPI’s Google app requests when a channel connects. You register no Google app and configure nothing.
The scope is also listed in Scopes.
The scopes a scoped API key needs, the credit cost of a post, and the MCP tools that publish are on Publishing.