Endpoint
POST https://api.reelsbuilder.ai/api/v1/clipper/youtubeSend exactly one source:
youtube_url— clip one video.channel_url— autoclipper: clip the channel's newest upload that your account has not clipped yet. Call it on your own schedule (for example daily per channel). Each call clips at most one new upload; videos you already clipped are skipped automatically, and failed clips can be retried.
Clip one video
curl -X POST https://api.reelsbuilder.ai/api/v1/clipper/youtube \
-H "Authorization: Bearer $REELSBUILDER_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"youtube_url": "https://www.youtube.com/watch?v=VIDEO_ID",
"clip_count": 3,
"aspect_ratio": "9:16",
"captions": true,
"focus": "A self-contained explanation of the migration problem",
"content_purpose": "education"
}'Autoclip a channel
curl -X POST https://api.reelsbuilder.ai/api/v1/clipper/youtube \
-H "Authorization: Bearer $REELSBUILDER_API_KEY" \
-H "Idempotency-Key: channel-acme-2026-10-07" \
-H "Content-Type: application/json" \
-d '{
"channel_url": "https://www.youtube.com/@acmecloud",
"clip_count": 3
}'Add "dry_run": true (single video or channel) to validate the request, see the price and, for a channel, which video would be clipped, without queueing or charging anything. No Idempotency-Key is needed.
# -> 200
{
"success": true,
"data": {
"dry_run": true,
"valid": true,
"mode": "clipper_channel",
"normalized_request": { "video_url": "https://www.youtube.com/@acmecloud", "numberOfClips": 3, "finalVideo_type": "Vertical", "captions": true, ... },
"price": { "usd_cents": 120, "display": "$1.20", "breakdown": [{ "item": "clip_youtube", "usd_cents": 120, "unit_usd_cents": 40, "quantity": 3 }] },
"estimated_render_seconds": { "min": 300, "max": 1800 },
"warnings": ["The clip provider can return fewer clips than requested; undelivered clips are refunded automatically."],
"source_mode": "channel",
"requested_clip_count": 3,
"source_video": { "youtube_video_id": "…", "title": "…", "url": "https://www.youtube.com/watch?v=…" },
"charged": false
}
}Parameters
| Field | Type | Description |
|---|---|---|
youtube_url | URL | One public YouTube video: watch?v=ID, youtu.be/ID, shorts/ID or live/ID. |
channel_url | URL | A channel: youtube.com/@handle, /channel/UC…, /c/name or /user/name. |
selection | enum | Channel only. newest_first (default) or oldest_first. Only the channel's ~15 most recent uploads are considered. |
clip_count | integer | 1–10. Default 5. A maximum — a source can yield fewer good clips. |
aspect_ratio | enum | 9:16 (default), 16:9 or 1:1. Alias: aspectRatio. |
captions | boolean | Burned-in captions. Default true. Alias: include_captions. |
focus | string | Up to 250 characters describing what to look for. |
content_purpose | enum | education, sales, awareness, product_demo, case_study, news or entertainment. Guides which segments are picked; speakers are never re-worded. |
dry_run | boolean | Free: validate, price and report the selected source without queueing or charging. See dry run. |
delivery | object | Optional. { "visibility": "private" } keeps the finished files in a private bucket instead of our public CDN; the job then returns links that expire after 24 hours. See Private delivery. |
Fields not listed here are ignored. Invalid values (for example a channel URL in youtube_url, or clip_count above 10) return 400 INPUT_INVALID before anything is queued. Only submit sources you have the rights to clip.
Response
{
"success": true,
"data": {
"job_id": "6a10…",
"video_id": "6a10…",
"status": "queued",
"poll_url": "/api/v1/jobs/6a10…",
"requested_clip_count": 3,
"price_usd_cents": 120,
"source_video": {
"youtube_video_id": "…",
"title": "…",
"url": "https://www.youtube.com/watch?v=…"
}
},
"jobId": "6a10…",
"videoId": "6a10…",
"meta": { "request_id": "…" }
}This is the standard receipt every Generate endpoint returns: the job id is data.job_id (also the X-Job-Id header; top-level jobId/videoId are deprecated aliases), and price_usd_cents is what was charged. source_video appears in channel mode. Poll poll_url every 10–15 seconds — see Jobs. A finished job lists every delivered clip in data.job.artifacts.videoUrls; count what you received, not what you requested. Add a webhook_url for a signed callback when the job ends (see Webhooks).
Channel outcomes
None of these are charged.
| Status | Code | Meaning |
|---|---|---|
| 409 | NO_NEW_CHANNEL_VIDEOS | Every recent upload has already been clipped by your account. Try again after the next upload. |
| 400 | CHANNEL_NOT_FOUND | No YouTube channel at that URL. |
| 502 | CHANNEL_UNAVAILABLE | YouTube did not return the channel feed. Retryable. |
Examples
TypeScript
const r = await fetch("https://api.reelsbuilder.ai/api/v1/clipper/youtube", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.REELSBUILDER_API_KEY}`,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({ channel_url: "https://www.youtube.com/@acmecloud", clip_count: 3 }),
});
const body = await r.json();
if (r.status === 409) console.log("No new upload yet");
else console.log(`Queued ${body.data.job_id} from ${body.data.source_video?.title}`);Python
import os, uuid, requests
r = requests.post(
"https://api.reelsbuilder.ai/api/v1/clipper/youtube",
headers={
"Authorization": f"Bearer {os.environ['REELSBUILDER_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
json={"youtube_url": "https://www.youtube.com/watch?v=VIDEO_ID", "clip_count": 3},
)
job = r.json()["data"]
print("queued", job["job_id"], "poll", job["poll_url"])Clip through MCP
Discover clip_youtube with tools/list on the authenticated MCP endpoint. It accepts the same single-video or channel source. Preview the input and price without a render using dry_run: true:
{
"jsonrpc": "2.0",
"id": 3,
"method": "tools/call",
"params": {
"name": "clip_youtube",
"arguments": {
"channel_url": "https://www.youtube.com/@acmecloud",
"clip_count": 3,
"dry_run": true
}
}
}Read result.structuredContent.data.price and data.normalized_request from this preview; it has no job to poll. Inspect isError and the structured error on failure. MCP does not publish clips. See MCP connection.
To generate the clips after approving the quote, call clip_youtube again without dry_run and with an idempotency_key (required for paid calls; reuse it only to retry the same request). Read data.job_id and data.poll_url from the result, or use REST with an Idempotency-Key header.
Pricing
- $0.40 per delivered clip from your prepaid API balance.
clip_count× $0.40 (5 clips by default) is reserved when the job is accepted. If the source has fewer strong moments and fewer clips come back, the difference is refunded automatically when the job completes. A failed job, or one that yields no clips, is refunded in full. - Dry runs and the channel outcomes above are never charged.
See also
- Quickstart — keys, polling and errors
- Errors
- Multi-Platform Post API — publish clips yourself