Skip to content

Guides

How to upload a video to YouTube through the SkedCast API

Upload a video to YouTube through the API by sending a title — it falls back to the first line of your caption if you omit it, but a video's title matters enough that you should send it explicitly. Everything else (category, privacy, COPPA self-declaration, license) has a sensible default.

Browse docs

6 min read

Before you publish#

You need one already-connected account for the platform. Connect it yourself in the Agency Console, or — if a client owns the account — mint a self-serve connect link with POST /clients/:id/connect-invites and send it to them; they authorize from that page without ever getting a SkedCast login.

GET /v1/accounts lists what's connected, with each account's id — that id is what you pass in targets.accountIds below.

Compose and schedule#

bash
curl -X POST https://api.skedcast.com/v1/posts \
  -H "Authorization: Bearer sked_live_YOUR_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "clientId": "<clientId>",
    "content": "Launch day is here 🚀",
    "mediaIds": ["<mediaAssetId>"],
    "targets": { "mode": "selection", "accountIds": ["<youtubeAccountId>"] },
    "schedule": { "type": "at", "scheduledAt": "2026-07-01T15:00:00Z" }
  }'
A minimal youtube post, scheduled for a specific time.

The YouTube API fields to upload a video#

Everything platform-specific goes in one variants entry with "platform": "youtube" and an overrides object. The adapter reads only the keys it declares (below) and ignores the rest — send youtube keys on a youtube variant, nothing more.

FieldTypeValues / defaultNotes
titlestring (≤100) — RequiredFalls back to the first line of content when unset.
privacyStatusenumpublic \| unlisted \| privateDefaults to the channel default when unset.
categoryIdenum stringe.g. "20" Gaming, "27" Education, "28" Science & TechnologyDefaults to "22" (People & Blogs).
madeForKidsbooleanfalseCOPPA self-declaration — always sent.
tagsstring[] or comma-separated stringsnippet.tags.
licenseenumyoutube \| creativeCommonDefaults to the Standard YouTube License.
descriptionstringOverrides the caption as the YouTube description.
firstCommentstringNeeds the youtube.force-ssl scope on the connection; without it Google answers 403 and the video still publishes. Posted right after publish. Best-effort: a failed comment never fails the post and is not reported, so verify on the published post.

Verbatim from the REST API reference's YouTube table.

With the platform-specific overrides#

json
{
  "clientId": "<clientId>",
  "content": "How bulk scheduling actually works, in 60 seconds.",
  "mediaIds": ["<videoAssetId>"],
  "coverMediaId": "<coverImageAssetId>",
  "targets": { "mode": "selection", "accountIds": ["<youtubeAccountId>"] },
  "variants": [
    {
      "platform": "youtube",
      "overrides": { "title": "Bulk scheduling in 60 seconds", "categoryId": "28", "madeForKids": false }
    }
  ],
  "schedule": { "type": "at", "scheduledAt": "2026-07-01T15:00:00Z" }
}
The same POST /posts body, with a variants entry added.

Checking the result#

Publishing fans out into one post target per account. GET /post-targets/:id (or GET /posts/:id) reports status, plus externalId (youtube's own post id) and permalink (its public URL) once published. Subscribe to the target.published / target.failed webhooks instead of polling if you can accept inbound HTTP — see the webhooks guide.

youtubeapipublish

FAQ

What happens if I don't send a title?
SkedCast falls back to the first line of your `content` caption. That's a plain-text fallback, not a generated title — send `overrides.title` explicitly for anything you actually want as the video's title.
How do I post a custom thumbnail?
Upload the image as its own media asset (the same presign → PUT → register sequence as any upload) and pass its id as the post-level `coverMediaId`. Omit it to use the auto-extracted poster frame.

Ready to broadcast everywhere?

Sign up free — no credit card. You land on the Free plan, and you can start a one-time 7-day Studio trial from your workspace whenever you are ready. Connect your first accounts, import a batch, and watch one post fan out across every platform.