YouTube API
Postproxy uploads videos to a connected YouTube channel. The post body becomes the video description; the video file is required.
Every request below uses the base URL https://api.postproxy.dev and an Authorization: Bearer YOUR_API_KEY header. Replace YOUR_API_KEY and the example IDs with your own.
Profiles and profile groups
Section titled “Profiles and profile groups”Every post targets one or more profiles. A profile is one connected account — for YouTube, a YouTube channel. Reference one in a request by its id (the prof_abc123 in the examples below) or by the platform name "youtube", which selects the group’s YouTube profile (a group holds at most one profile per platform). List what’s connected with GET /api/profiles.
Profiles live in profile groups — containers that organize the accounts for one brand, client, or project. List groups with GET /api/profile_groups, and connect a new YouTube profile with the Initialize Connection endpoint.
Example: get profiles and profile groups
List the profiles you can post to — GET /api/profiles:
curl -X GET "https://api.postproxy.dev/api/profiles" \ -H "Authorization: Bearer YOUR_API_KEY"{ "data": [ { "id": "prof_abc123", "name": "My Channel", "platform": "youtube", "status": "active", "profile_group_id": "grp_xyz789", "expires_at": null, "post_count": 31, "avatar_url": "https://cdn.postproxy.dev/uploads/avatar_prof_abc123.jpg" } ]}List your profile groups — GET /api/profile_groups:
curl -X GET "https://api.postproxy.dev/api/profile_groups" \ -H "Authorization: Bearer YOUR_API_KEY"{ "data": [ { "id": "grp_xyz789", "name": "Main Brand", "profiles_count": 5 }, { "id": "grp_def456", "name": "Client Project", "profiles_count": 3 } ]}At a glance
Section titled “At a glance”| Platform ID | youtube |
| Formats | post (channel video) |
| Character limit | 5,000 (description); title 100 |
| Media | Required — video only |
| Comments | Coming soon |
| Direct messages | No |
| Post chains | No |
Publishing
Section titled “Publishing”Parameters
Section titled “Parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
privacy_status | string | No | public, unlisted, or private (defaults to public) |
title | string | No | Video title (max 100 characters) |
cover_url / cover_file | string / file | No | Custom thumbnail (requires a verified YouTube account) |
made_for_kids | boolean | No | Whether the video is made for kids |
tags | array | No | Tags for the video |
category_id | string | No | YouTube category ID (defaults to "22", People & Blogs) |
contains_synthetic_media | boolean | No | Disclose altered or AI-generated content |
| Media | Max size | Formats | Count | Duration |
|---|---|---|---|---|
| Video | 256 GB | mp4, mov, avi, wmv, flv, 3gp | 1 | 1 s+ |
- A video is required; images are not accepted.
- The post
bodybecomes the video description.
Privacy status
Section titled “Privacy status”| Value | Visibility |
|---|---|
public | Everyone |
unlisted | Anyone with the link |
private | Only you |
# Public upload with a custom thumbnailcurl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "Check out our latest tutorial on building API integrations!" }, "profiles": ["prof_abc123"], "media": ["https://example.com/video.mp4"], "platforms": { "youtube": { "title": "How to Build an API Integration", "privacy_status": "public", "cover_url": "https://example.com/custom-thumbnail.jpg" } } }'# Unlisted upload with tags and a categorycurl -X POST "https://api.postproxy.dev/api/posts" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "post": { "body": "Internal demo recording." }, "profiles": ["prof_abc123"], "media": ["https://example.com/demo.mp4"], "platforms": { "youtube": { "title": "Q3 Demo", "privacy_status": "unlisted", "tags": ["demo", "product"], "category_id": "28", "made_for_kids": false } } }'Comments
Section titled “Comments”Coming soon. Comment list, reply, hide, and delete support for YouTube is in progress. When live, comments will be managed through the Comments API.
Direct messages
Section titled “Direct messages”Not supported.
Postproxy records periodic stat snapshots you can pull as a timeseries; field names pass through from YouTube unchanged.
Profile stats
Section titled “Profile stats”Channel-level metrics, refreshed roughly every 23 hours via the Profile stats endpoint (GET /api/profiles/:id/stats).
Fields: subscriberCount, viewCount, videoCount
# Fetch the profile stats timeseriescurl "https://api.postproxy.dev/api/profiles/prof_abc123/stats" \ -H "Authorization: Bearer YOUR_API_KEY"Post stats
Section titled “Post stats”Per-video engagement, captured after publish via the Post stats endpoint (GET /api/posts/stats).
Fields: impressions, likes, comments, saved
# Fetch post statscurl "https://api.postproxy.dev/api/posts/stats?post_ids=post_abc123&profiles=youtube" \ -H "Authorization: Bearer YOUR_API_KEY"Webhooks
Section titled “Webhooks”Subscribe with the Webhooks API:
curl -X POST "https://api.postproxy.dev/api/webhooks" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhooks/postproxy", "events": ["platform_post.published", "platform_post.failed", "platform_post.insights"] }'Events relevant to YouTube:
| Event | When |
|---|---|
post.processed | A post is ready to publish |
platform_post.published | A post was published to the platform |
platform_post.failed | A post failed to publish (retries exhausted) |
platform_post.failed_waiting_for_retry | A publish attempt failed; will retry |
platform_post.insights | New analytics snapshot |
profile.connected / .disconnected | Connection state changed |
profile.stats | New profile stats snapshot |
media.failed | A media attachment failed to process |
privacy_statusis optional and defaults topublicwhen omitted.- A custom thumbnail (
cover_url/cover_file) requires a verified YouTube account. - Set
contains_synthetic_media: trueto disclose AI-generated or altered content, per YouTube policy.