Posts
The posts endpoints publish a rendered clip to your team’s connected social platforms. The flow follows the same draft → edit → publish pattern the dashboard uses, so AI-generated captions are already there when you start.
How it works
Section titled “How it works”-
Generate a clip with POST /v1/clips, then poll GET /v1/clips/:jobId until the clips’ previews are ready.
-
Drafts auto-create. When a clip’s preview is ready, Choppity generates a
draftpost per connected platform — one for YouTube, one for TikTok, etc. Each draft has an AI-written, platform-tailored caption (and title for YouTube) ready to review. -
Read the drafts with
GET /v1/clips/:clipId/posts. -
Edit anything you want with
PUT /v1/posts/:postId— caption, title, TikTok privacy, YouTube category. -
Publish with
POST /v1/posts/:postId/publish. Pass ascheduled_atto schedule it for later, or omit it to go out immediately.
GET /v1/clips/:clipId/posts
Section titled “GET /v1/clips/:clipId/posts”Lists every post (drafts, scheduled, published, failed, cancelled) for a clip.
Auth: Bearer JWT or API key
Path parameters
Section titled “Path parameters”| Param | Type | Description |
|---|---|---|
clipId | string | A clip id from GET /v1/clips/:jobId |
Response · 200 OK
Section titled “Response · 200 OK”{ "posts": [ { "id": "9d8e7f6a-...", "clip_id": "fc3eb2a1-...", "platform": "youtube", "status": "draft", "caption": "Three things I wish I'd known about onboarding...", "title": "How we onboarded 1000 users in a week", "youtube": { "category_id": "22" } }, { "id": "4b3a2c1d-...", "clip_id": "fc3eb2a1-...", "platform": "tiktok", "status": "draft", "caption": "Three things I wish I'd known... 🧵", "tiktok": { "privacy_level": "PUBLIC_TO_EVERYONE", "disable_comment": false, "disable_duet": true, "disable_stitch": true, "brand_content_toggle": false, "brand_organic_toggle": false } } ]}GET /v1/posts/:postId
Section titled “GET /v1/posts/:postId”Reads a single post.
Auth: Bearer JWT or API key
Response · 200 OK
Section titled “Response · 200 OK”{ "post": { "id": "9d8e7f6a-...", "clip_id": "fc3eb2a1-...", "platform": "youtube", "status": "published", "caption": "Three things I wish I'd known...", "title": "How we onboarded 1000 users in a week", "published_at": 1745800120000, "published_url": "https://www.youtube.com/watch?v=abc123", "youtube": { "category_id": "22" } }}| Field | Type | Description |
|---|---|---|
id | string | Post id |
clip_id | string | The clip the post is for |
platform | string | youtube · tiktok · instagram · linkedin |
status | string | draft · scheduled · queued · processing · uploading · published · failed · cancelled |
caption | string | YouTube description / TikTok / Instagram / LinkedIn caption |
title | string | YouTube only |
scheduled_at | number | Unix-ms — present when status === "scheduled" |
published_at | number | Unix-ms — present when status === "published" |
published_url | string | Direct link to the live post — present when status === "published" |
error | string | Human-readable failure reason — present when status === "failed" |
tiktok | object | TikTok-only settings (see below) |
youtube | object | YouTube-only settings (see below) |
YouTube settings
Section titled “YouTube settings”| Field | Type | Description |
|---|---|---|
category_id | string | YouTube category id (e.g. "22" for People & Blogs) |
TikTok settings
Section titled “TikTok settings”| Field | Type | Description |
|---|---|---|
privacy_level | string | PUBLIC_TO_EVERYONE · MUTUAL_FOLLOW_FRIENDS · FOLLOWER_OF_CREATOR · SELF_ONLY |
disable_comment | boolean | When true, comments are turned off |
disable_duet | boolean | When true, duets are turned off |
disable_stitch | boolean | When true, stitches are turned off |
brand_content_toggle | boolean | TikTok branded-content disclosure |
brand_organic_toggle | boolean | TikTok organic-promotion disclosure |
PUT /v1/posts/:postId
Section titled “PUT /v1/posts/:postId”Updates a draft post. Only posts with status === "draft" are editable.
Auth: Bearer JWT or API key
Request body
Section titled “Request body”| Field | Type | Description |
|---|---|---|
caption | string | New caption (or YouTube description). Platform-specific length limits apply. |
title | string | YouTube only — new video title (max 100 chars) |
tiktok | object | TikTok-only — partial settings to merge over the existing draft |
youtube | object | YouTube-only — partial settings to merge over the existing draft |
curl -X PUT https://api2.choppity.com/v1/posts/$POST_ID \ -H "Authorization: Key $CHOPPITY_KEY" \ -H "Content-Type: application/json" \ -d '{ "caption": "My new caption", "tiktok": { "privacy_level": "PUBLIC_TO_EVERYONE" } }'Response · 200 OK
Section titled “Response · 200 OK”The full updated post (same shape as GET /v1/posts/:postId).
POST /v1/posts/:postId/publish
Section titled “POST /v1/posts/:postId/publish”Publishes a draft. Pass scheduled_at to schedule for later (must be at
least 5 minutes in the future), or omit to go out immediately.
Auth: Bearer JWT or API key
Request body
Section titled “Request body”| Field | Type | Description |
|---|---|---|
scheduled_at | number | Optional. Unix-ms when the post should publish. ≥ 5 minutes in the future. |
# Publish immediatelycurl -X POST https://api2.choppity.com/v1/posts/$POST_ID/publish \ -H "Authorization: Key $CHOPPITY_KEY" \ -H "Content-Type: application/json" \ -d '{}'
# Schedule for an hour from nowcurl -X POST https://api2.choppity.com/v1/posts/$POST_ID/publish \ -H "Authorization: Key $CHOPPITY_KEY" \ -H "Content-Type: application/json" \ -d "{\"scheduled_at\": $(date -v+1H +%s)000}"Response · 202 Accepted
Section titled “Response · 202 Accepted”The full post with its new status (queued for immediate, scheduled
for future). Subscribe to post.published / post.failed
webhook events to learn the outcome
without polling.
{ "post": { "id": "9d8e7f6a-...", "clip_id": "fc3eb2a1-...", "platform": "youtube", "status": "queued", "caption": "..." }}DELETE /v1/posts/:postId
Section titled “DELETE /v1/posts/:postId”Cancels a post in draft, scheduled, or queued status. Once a post
moves to processing we can no longer pull it back.
Auth: Bearer JWT or API key
Response · 200 OK
Section titled “Response · 200 OK”The full post with status: "cancelled".
{ "post": { "id": "9d8e7f6a-...", "clip_id": "fc3eb2a1-...", "platform": "youtube", "status": "cancelled", "caption": "..." }}End-to-end example
Section titled “End-to-end example”# 1. Read draftsDRAFTS=$(curl -s https://api2.choppity.com/v1/clips/$CLIP_ID/posts \ -H "Authorization: Key $CHOPPITY_KEY")YT_POST_ID=$(echo "$DRAFTS" | jq -r '.posts[] | select(.platform=="youtube") | .id')
# 2. Edit captioncurl -X PUT https://api2.choppity.com/v1/posts/$YT_POST_ID \ -H "Authorization: Key $CHOPPITY_KEY" \ -H "Content-Type: application/json" \ -d '{ "caption": "My final caption" }'
# 3. Publish nowcurl -X POST https://api2.choppity.com/v1/posts/$YT_POST_ID/publish \ -H "Authorization: Key $CHOPPITY_KEY" \ -H "Content-Type: application/json" \ -d '{}'const KEY = process.env.CHOPPITY_KEY;const auth = { Authorization: `Key ${KEY}`, 'Content-Type': 'application/json' };
// 1. Read draftsconst { posts } = await fetch( `https://api2.choppity.com/v1/clips/${clipId}/posts`, { headers: auth }).then((r) => r.json());const yt = posts.find((p) => p.platform === 'youtube');
// 2. Edit captionawait fetch(`https://api2.choppity.com/v1/posts/${yt.id}`, { method: 'PUT', headers: auth, body: JSON.stringify({ caption: 'My final caption' }),});
// 3. Publish nowawait fetch(`https://api2.choppity.com/v1/posts/${yt.id}/publish`, { method: 'POST', headers: auth, body: JSON.stringify({}),});Errors
Section titled “Errors”| Code | HTTP | When |
|---|---|---|
BAD_REQUEST | 400 | Invalid body. Common cases: editing a non-draft post, sending title / youtube settings to a non-YouTube post, sending tiktok settings to a non-TikTok post, scheduled_at less than 5 minutes in the future, no active connection for the post’s platform. |
UNAUTHORIZED | 401 | Missing or invalid credential |
NOT_FOUND | 404 | postId doesn’t exist on your team |