API reference
REST over HTTPS, JSON in and out, workspace-scoped bearer keys. Create keys under Settings → API keys; they look like cc_live_… and are shown once.
Authentication
Authorization: Bearer cc_live_xxxxxxxxxxxxxxxxPOST/media
Stage a video. Returns a presigned upload URL — PUT the file bytes there, then the asset is ready to attach to posts.
curl -X POST https://crosscast.io/api/v1/media \
-H "Authorization: Bearer cc_live_..." \
-H "Content-Type: application/json" \
-d '{ "filename": "final.mp4", "bytes": 18422011 }'
# → 201
{ "id": "med_01hxkq...", "upload_url": "https://...", "expires_in": 3600 }
curl -X PUT "<upload_url>" --data-binary @final.mp4 -H "Content-Type: video/mp4"POST/posts
Create a post. Targets default to the channel's accounts; captions default to the channel's templates rendered with your title. Both are overridable per call.
curl -X POST https://crosscast.io/api/v1/posts \
-H "Authorization: Bearer cc_live_..." \
-H "Content-Type: application/json" \
-d '{
"channel": "mapsofwhy",
"media_id": "med_01hxkq...",
"title": "why the mississippi runs backwards",
"schedule": "next_slot", // or "now", or "2026-08-14T17:00:00Z"
"captions": { // optional per-platform overrides
"tiktok": "why the mississippi runs backwards #maps #geography"
},
"cover_offset_ms": 1200, // optional
"accounts": ["acc_01..."] // optional subset of the channel
}'
# → 201
{ "id": "post_01hxkr...", "status": "scheduled",
"targets": [
{ "id": "tgt_01...", "platform": "tiktok", "account": "@mapsofwhy", "at": "2026-08-14T17:00:00Z" },
{ "id": "tgt_02...", "platform": "instagram", "account": "@mapsofwhy", "at": "2026-08-14T17:00:00Z" },
{ "id": "tgt_03...", "platform": "youtube", "account": "mapsofwhy", "at": "2026-08-14T17:00:00Z" }
] }GET/posts/:id
Status, permalinks, and the latest metrics snapshot per target.
curl https://crosscast.io/api/v1/posts/post_01hxkr... \
-H "Authorization: Bearer cc_live_..."
# → 200
{ "id": "post_01hxkr...", "status": "published",
"targets": [
{ "platform": "instagram", "status": "published",
"permalink": "https://www.instagram.com/reel/...",
"metrics": { "views": 8211, "likes": 402, "avg_watch_time_ms": 11400 } },
{ "platform": "tiktok", "status": "on_phone",
"note": "delivered to TikTok inbox; finish in-app" }
] }Errors
Standard HTTP status codes with a stable machine-readable shape. Platform-side failures include the platform's own message verbatim — debugging distribution should never require guessing.
{ "error": { "code": "quota_exceeded",
"message": "YouTube upload quota reached for today (6/6). Next reset 08:00 UTC." } }