Platforms

YouTube

Connect a YouTube channel, upload and schedule videos and Shorts, manage comments and likes, and read video analytics.

Upload videos and Shorts, manage comments, like videos and read metrics.

Quick Reference

PropertyValue
Account typesThe signed-in Google account's channel
Connection methodGoogle OAuth
Post typesvideo
Max media per post1
Text limit5,000 characters, title 100
ThreadsNo
QuotesNo
Remote delete
Comments
Likes
RepostsNo
BookmarksNo
Direct messagesNo
Post analytics
Account analyticsNo

Every post is exactly 1 video. Its text becomes the description. The title comes from the text unless you set youtube.title.

Connect

Sign in with the Google account that owns the channel. Without a channel, it fails. Connect in Dashboard → Connections, or with a connect session.

Permissions

ScopeUsed for
youtube.uploadUploading videos
youtube.force-sslComments, likes, deletes, uploads list and stats
yt-analytics.readonlyAnalytics, including shares

Google lets the owner skip permissions. Missing ones fail with a *_PERMISSION code until you reconnect and grant them.

Staying Connected

Access renews itself, so canAutoRenew is true.

It ends if the owner removes access in Google. You then get TOKEN_INVALID. Reconnect with the same Google account. The id stays the same.

Publish

import { Configuration, PostsApi } from "@onepostly/sdk";

const postsApi = new PostsApi(
  new Configuration({ accessToken: process.env.ONEPOSTLY_API_KEY })
);

const response = await postsApi.createPost({
  createPostBody: {
    "text": "Build a REST API from scratch",
    "mediaKind": "video",
    "media": [
      {
        "url": "https://cdn.onepostly.com/media/rest-api-tutorial.mp4"
      }
    ],
    "accounts": [
      {
        "accountId": "acc_YOUR_YOUTUBE_ACCOUNT_ID",
        "youtube": {
          "title": "Build a REST API from Scratch",
          "description": "A step by step walkthrough.\n\n00:00 Intro\n02:15 Routes",
          "privacyStatus": "public",
          "tags": [
            "api",
            "tutorial"
          ],
          "categoryId": "27"
        }
      }
    ]
  },
});
console.log(response);
{
  "groupId": "grp_7d2e5b1a9c4f4a68b3e07f1c2d9a6e45",
  "data": [
    {
      "id": "pst_3c8a2d6e91b44f7a8e250d6b4c1f9a73",
      "groupId": "grp_7d2e5b1a9c4f4a68b3e07f1c2d9a6e45",
      "accountId": "acc_YOUR_YOUTUBE_ACCOUNT_ID",
      "platform": "youtube",
      "source": "onepostly",
      "status": "publishing",
      "text": "Build a REST API from scratch",
      "mediaKind": "video",
      "media": [
        {
          "url": "https://cdn.onepostly.com/media/rest-api-tutorial.mp4"
        }
      ],
      "thread": [],
      "scheduledFor": null,
      "timezone": null,
      "options": {
        "youtube": {
          "title": "Build a REST API from Scratch",
          "description": "A step by step walkthrough.\n\n00:00 Intro\n02:15 Routes",
          "privacyStatus": "public",
          "tags": [
            "api",
            "tutorial"
          ],
          "categoryId": "27"
        }
      },
      "platformPostId": null,
      "url": null,
      "error": null,
      "publishedAt": null,
      "metrics": null,
      "createdAt": "2027-03-15T09:00:00.000Z",
      "updatedAt": "2027-03-15T09:00:00.000Z"
    }
  ]
}

Once published, platformPostId is the video id and url its watch link.

Post Types

mediaKindPublishesMedia
videoA video or a ShortExactly 1 video, up to 256 MB

Any other mediaKind returns 400 VALIDATION_ERROR.

Shorts

A Short is a normal upload, with no flag. YouTube decides by its shape. It must be vertical or square and up to 3 minutes long.

Options

Options go under youtube. Another platform's options there return 400.

Prop

Type

categoryIdCategory
10Music
20Gaming
22People and Blogs
27Education
28Science and Technology

An unknown category fails the post with VALIDATION_ERROR.

Title and Description

Without title, the title is the text on one line, cut at 100 with .... Empty text gives the title "Untitled video". Without description, it is the text. Both are plain text, so Markdown and HTML show as typed.

First Comment

If YouTube refuses firstComment, the video still publishes. A madeForKids video has comments off, so its first comment never posts.

Media Requirements

These are YouTube's limits, on top of the Media URL Requirements.

MediaFormatsMax size
VideosMP4, MOV, AVI and WebM256 MB

A file outside these formats and sizes is refused. See Platform Limits.

PropertyRequirement
RecommendedMP4, H.264 and AAC
Regular video16:9, 1080p or higher
Short9:16 or 1:1, up to 3 minutes
DurationUp to 15 minutes without phone verification

A URL must send a Content-Length header. Uploaded files always do.

Large videos keep processing after published. Do not upload again.

Scheduling, Editing and Deleting

Scheduling and editing work as usual. The video uploads at the scheduled time. A published video returns NOT_EDITABLE. Delete it and upload it again.

Deleting removes the video, including one uploaded outside Onepostly. One already gone counts as deleted. A delete during upload returns POST_PUBLISHING.

Engagement

See Comments and Likes and Reposts for the requests.

ActionSupportedNotes
List commentsTop-level, 50 per page, with some replies
Comment or replyAs the channel, up to 10,000 characters
Delete a commentOnes the channel owns or moderates
Like or unlike a videoAny video, as the channel
Hide or like a commentNoUNSUPPORTED_PLATFORM
Repost, quote, bookmarkNoUNSUPPORTED_PLATFORM

Comments need the video's pst_ id. Outside videos get one after a sync. Likes also take any YouTube video id. Another account's pst_ id fails.

import { Configuration, EngagementApi } from "@onepostly/sdk";

const engagementApi = new EngagementApi(
  new Configuration({ accessToken: process.env.ONEPOSTLY_API_KEY })
);

const response = await engagementApi.likePost({
  id: "acc_YOUR_YOUTUBE_ACCOUNT_ID",
  postId: "dQw4w9WgXcQ",
});
console.log(response);
{
  "postId": "pst_3c8a2d6e91b44f7a8e250d6b4c1f9a73",
  "accountId": "acc_YOUR_YOUTUBE_ACCOUNT_ID",
  "platform": "youtube",
  "liked": true
}

Commenting on a video with comments off returns COMMENTS_PERMISSION.

Inbox

YouTube has no inbox through Onepostly.

Analytics

Metrics

FieldYouTube metricNotes
impressionsViewsSame as views
reachNoneAlways null
viewsViews
likesLikes
commentsComments
sharesSharesNeeds yt-analytics.readonly
savesNoneAlways null
engagementLikes + comments + shares

Read Post Analytics

import { Configuration, AnalyticsApi } from "@onepostly/sdk";

const analyticsApi = new AnalyticsApi(
  new Configuration({ accessToken: process.env.ONEPOSTLY_API_KEY })
);

const response = await analyticsApi.getPostAnalytics({
  id: "pst_3c8a2d6e91b44f7a8e250d6b4c1f9a73",
});
console.log(response);
{
  "postId": "pst_3c8a2d6e91b44f7a8e250d6b4c1f9a73",
  "accountId": "acc_1699f4157fb643f49d2ac447491f32a8",
  "platform": "youtube",
  "status": "ready",
  "metrics": {
    "impressions": 456,
    "reach": null,
    "likes": 123,
    "comments": 12,
    "shares": 4,
    "saves": null,
    "views": 456,
    "engagement": 139
  },
  "fetchedAt": "2027-03-15T10:00:00.000Z",
  "error": null
}

Freshness is the standard. Shares arrive a few days after the rest. A new video reads pending. A private one can stay pending until you reconnect. A removed video reads unavailable with VIDEO_NOT_FOUND, for good.

At capacity, it reads failed with QUOTA_EXCEEDED for a while.

List Account Media lists uploads, 20 per page. Its metrics and durationSec are null. It includes videos uploaded outside.

Limitations

Not available for YouTube through Onepostly.

  • Text and image posts
  • Threads and quotes
  • Custom thumbnails
  • Playlists, end screens and captions
  • Community posts, Premieres and live streams
  • Editing a published video
  • Deleting outside videos
  • Hiding or liking comments
  • Direct messages
  • Channel stats

Errors

Breaking a rule on this page returns 400 VALIDATION_ERROR and creates nothing. YouTube can also refuse the metadata at upload, failing the post the same way. Every code is in Errors, with its cause and fix.

Publish Errors

CodeCauseFix
INVALID_MEDIAAn empty fileSend a video that plays
MEDIA_UNFETCHABLENo download, or no Content-LengthUpload the file instead
MEDIA_UPLOAD_FAILEDYouTube rejected the fileRe-encode as MP4
PUBLISH_FAILEDYouTube did not confirm the uploadCheck YouTube Studio first
UPLOAD_LIMIT_EXCEEDEDYouTube's daily upload limitPost again the next day
QUOTA_EXCEEDEDYouTube is at capacityTry again in a few hours
PERMISSION_DENIEDA suspended channel or missing permissionCheck the channel, then reconnect
NOT_EDITABLEAn edit after publishDelete and upload again
POST_PUBLISHINGA delete during uploadDelete once published

Engagement Errors

CodeCauseFix
POST_ACCOUNT_MISMATCHAnother account's pst_ idUse the YouTube video id
COMMENTS_PERMISSIONComments off, or not the channel's commentTurn comments on, or skip it
ENGAGEMENT_PERMISSIONThe channel cannot rate videosReconnect with every permission

Analytics Errors

CodeCauseFix
ANALYTICS_PENDINGNo metrics yetRead again later
VIDEO_NOT_FOUNDThe video is goneStop reading it
QUOTA_EXCEEDEDYouTube is at capacityRead again in a few hours
LIST_FAILEDUploads did not loadTry again later