YouTube
SimplePost uploads videos to YouTube through the YouTube Data API v3. YouTube access is tied to a Google account and channel, so authenticate as the channel owner or a Brand Account manager.
Content support
| Capability | Support |
|---|---|
| Media | Videos only. |
| Title | Required. Up to 100 characters. |
| Description | Optional. Up to 5000 characters. |
| Optional fields | tags, categoryId, playlistId, thumbnailPath, thumbnailUrl, selfDeclaredMadeForKids. |
| Scheduler thumbnail | Upload a JPG/PNG custom thumbnail in the YouTube per-account options, or pass accountOptions[accountId].thumbnailUrl through the Scheduler API. |
| Shorts | Use a normal upload; YouTube classifies Shorts based on duration and aspect ratio. |
| Native scheduling | publishAt option (ISO 8601 timestamp). |
When publishAt is set, SimplePost posts the video as private regardless of the supplied privacyStatus and lets YouTube flip it public at the scheduled time.
Set up credentials
The fastest path is the CLI bundled OAuth client (simplepost account add youtube) or the Scheduler app. Use the steps below only when you want to drive the SDK directly with your own Google project.
1. Create or select a Google Cloud project
Open the Google Cloud Console and create or select a project dedicated to SimplePost.
2. Enable YouTube Data API v3
Open APIs & Services, find YouTube Data API v3, and enable it.
3. Configure OAuth consent
Configure the OAuth consent screen. Add upload scopes:
https://www.googleapis.com/auth/youtube.upload
https://www.googleapis.com/auth/youtube
Add yourself as a test user while the app is in testing mode.
4. Create OAuth client credentials
Create OAuth 2.0 Client ID credentials with application type Web application. Add the redirect URI used by your app or Scheduler deployment.
For local manual testing, a redirect URI like this is common:
http://localhost:3000/youtube
Save the Client ID and Client Secret.
5. Generate tokens
Run an OAuth authorization flow with access_type=offline and prompt=consent so Google returns a refresh token. Store the refresh token for long-lived uploads.
Environment variables
YOUTUBE_CLIENT_ID=
YOUTUBE_CLIENT_SECRET=
YOUTUBE_REFRESH_TOKEN=
All three variables must be set together. The shorter accessToken-only credential variant is supported through options.youtube.credentials.accessToken but not through env vars.
SDK options
await post({
content: {
media: [
{
type: "video",
path: "./video.mp4",
title: "Launch demo",
description: "A short demo",
},
],
},
platforms: ["youtube"],
options: {
youtube: {
privacyStatus: "unlisted",
tags: ["demo", "launch"],
categoryId: "22",
playlistId: "PL1234567890",
thumbnailPath: "./thumbnail.jpg",
selfDeclaredMadeForKids: false,
publishAt: "2030-01-01T12:00:00Z",
},
},
});
Common category IDs:
| ID | Category |
|---|---|
| 10 | Music |
| 20 | Gaming |
| 22 | People & Blogs |
| 23 | Comedy |
| 24 | Entertainment |
| 25 | News & Politics |
| 26 | Howto & Style |
| 27 | Education |
| 28 | Science & Technology |
Custom thumbnails can be supplied either on the video media item or in options.youtube. The YouTube option takes precedence:
await post({
content: {
media: [{ type: "video", path: "./video.mp4", title: "Launch demo" }],
},
platforms: ["youtube"],
options: {
youtube: {
thumbnailPath: "./thumbnail.jpg",
// or thumbnailUrl: "https://cdn.example.com/thumbnail.jpg"
},
},
});
For Scheduler API calls, upload the thumbnail first, then set the returned public URL in per-account options:
{
"accountOptions": {
"youtube-account-id": {
"thumbnailUrl": "https://cdn.example.com/thumbnail.jpg"
}
}
}
REST server account
Add this entry under accounts in the self-hosted REST server's accounts.json:
{
"id": "youtube-main",
"platform": "youtube",
"credentials": {
"clientId": "...",
"clientSecret": "...",
"refreshToken": "..."
},
"options": {
"privacyStatus": "public",
"categoryId": "22",
"thumbnailUrl": "https://cdn.example.com/thumbnail.jpg"
}
}