API Endpoints
Complete reference of all available API endpoints.
API Endpoints
This page provides a quick reference of all available endpoints. For interactive documentation with request/response examples, visit the Swagger UI.
Authentication
| Method | Endpoint | Description |
|---|---|---|
| GET | /auth/verify | Verify API key and get organization info |
Account
| Method | Endpoint | Description |
|---|---|---|
| GET | /account/credits | Get credit balance |
| GET | /account/usage | Get usage history |
Clips
AI Clips turns long YouTube videos into short-form MP4s for YouTube Shorts, TikTok, and Reels. Analysis is free. Rendering finished clips costs 2 credits per clip.
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| GET | /clips/projects | List clip projects | - |
| POST | /clips/projects | Analyze a YouTube video and create a clip project | Free |
| GET | /clips/projects/{projectId} | Get analyzed clips and source-video readiness | - |
| GET | /clips/projects/{projectId}/renders | List render jobs for a project | - |
| POST | /clips/projects/{projectId}/renders | Render one or more clips to MP4 | 2 per clip |
| GET | /clips/renders/{renderId} | Poll a render job status and output URL | - |
AI Clips Workflow
The clips API is asynchronous:
- Create a project with
POST /clips/projects - Save clip IDs from
data.clips - Poll
GET /clips/projects/{projectId}untildata.downloadStatusis"ready" - Start renders with
POST /clips/projects/{projectId}/renders - Poll
GET /clips/renders/{renderId}untildata.statusis"completed" - Download the finished MP4 from
data.outputUrl
Analyze Video for Clips
POST /clips/projects accepts a YouTube URL and returns ranked short-form moments. It also starts preparing the source video in the background.
| Parameter | Type | Required | Description |
|---|---|---|---|
youtube_url | string | Yes | Full YouTube video URL |
format | string | No | "portrait" for 9:16 output (default) or "landscape" for 16:9 output |
{
"youtube_url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"format": "portrait"
}Response:
{
"data": {
"id": "project_uuid",
"videoTitle": "How I built my channel",
"downloadStatus": "downloading",
"format": "portrait",
"analysis": {
"contentType": "tutorial",
"suggestedFormat": "portrait",
"suggestedStyle": "bold"
},
"clips": [
{
"id": "clip-1",
"title": "The moment everything changed",
"startTime": 42.5,
"endTime": 78.2,
"hook": "A strong before-and-after reveal that works as a standalone short.",
"category": "story",
"viralScore": 8.7,
"hookStrength": "strong",
"platformFit": ["Shorts", "TikTok", "Reels"],
"mood": "inspiring",
"keywords": ["changed", "built", "result"]
}
]
}
}Get Clip Project
Use GET /clips/projects/{projectId} to poll readiness. Renders require downloadStatus to be "ready"; otherwise the render endpoint returns 409.
{
"data": {
"id": "project_uuid",
"downloadStatus": "ready",
"clips": []
}
}Render Clips
POST /clips/projects/{projectId}/renders accepts one clip ID or up to 10 clip IDs. Failed render jobs are refunded by the render pipeline.
| Parameter | Type | Required | Description |
|---|---|---|---|
clip_id | string | Either/or | Render a single clip |
clip_ids | string[] | Either/or | Render multiple clips, up to 10 |
format | string | No | "portrait" or "landscape" |
subtitle_style | string | No | "bold", "clean", "minimal", "energetic", or "glow" |
brand_id | uuid | No | Brand used for brand frame and end-card logo |
options | object | No | Render customizations |
Render options:
| Option | Type | Description |
|---|---|---|
music | boolean | Add background music when available |
musicTrackId | string | Use a specific music track instead of the AI pick |
broll | boolean | Generate and insert contextual AI b-roll |
hookTitle | boolean | Add an animated hook title intro |
progressBar | boolean | Add a short-form progress indicator |
brandFrame | boolean | Add a brand-colored frame; requires brand_id |
endCardText | string | CTA text for the end card, max 120 characters |
keywordEmphasis | boolean | Highlight important words in captions |
{
"clip_ids": ["clip-1", "clip-2"],
"format": "portrait",
"subtitle_style": "bold",
"options": {
"music": true,
"broll": true,
"hookTitle": true,
"progressBar": true,
"keywordEmphasis": true,
"endCardText": "Follow for more"
}
}Response:
{
"data": {
"renders": [
{
"id": "render_uuid",
"clipId": "clip-1",
"status": "pending",
"creditsCharged": 2
}
],
"creditsCharged": 4
}
}Poll Render Status
GET /clips/renders/{renderId} returns render progress. When status is "completed", use outputUrl to download the MP4.
{
"data": {
"id": "render_uuid",
"projectId": "project_uuid",
"clipId": "clip-1",
"status": "completed",
"progress": 100,
"currentStep": "finalize",
"format": "portrait",
"outputUrl": "https://storage.example.com/clips/render_uuid.mp4",
"creditsCharged": 2,
"error": null,
"createdAt": "2026-06-13T18:30:00.000Z",
"completedAt": "2026-06-13T18:33:12.000Z"
}
}Thumbnails
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| GET | /thumbnails | List thumbnails | - |
| POST | /thumbnails | Generate a thumbnail | 1 |
| GET | /thumbnails/{id} | Get thumbnail details | - |
| DELETE | /thumbnails/{id} | Delete a thumbnail | - |
| POST | /thumbnails/analyze | Analyze video for concepts | - |
| POST | /thumbnails/variations | Generate variations | 1 each |
Generate Thumbnail Parameters
The POST /thumbnails endpoint accepts these parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
prompt | string | Yes | Thumbnail description/concept |
styleId | uuid | No | Style to apply |
brandId | uuid | No | Brand for colors |
faceIds | uuid[] | No | Faces to include |
referenceImageUrls | url[] | No | Reference images for style guidance (no Style required) |
aspectRatio | string | No | "16:9" (default) or "9:16" |
collectionId | uuid | No | Collection to add thumbnail to |
Analyze Video for Concepts
POST /thumbnails/analyze returns three AI-generated thumbnail concepts (each with a ready-to-use prompt) for a video. Provide either a YouTube URL or a transcript — exactly one is required.
| Parameter | Type | Required | Description |
|---|---|---|---|
youtubeUrl | string | Either/or | YouTube URL — we fetch the transcript |
transcript | string | Either/or | Full transcript (≥50 chars). Use this for unlisted/private videos, podcasts, or any source where the transcript isn't auto-discoverable |
videoTitle | string | No | Title used to anchor concepts when sending a transcript. Defaults to "Your Video" |
From a YouTube URL:
{
"youtubeUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}From a transcript:
{
"transcript": "In this episode we break down how creators are using AI to generate thumbnails at scale. The first thing we noticed...",
"videoTitle": "How creators 10x'd CTR with AI thumbnails"
}Response:
{
"data": {
"video": {
"title": "How creators 10x'd CTR with AI thumbnails",
"summary": "..."
},
"concepts": [
{
"id": "concept-1",
"title": "...",
"description": "...",
"prompt": "...",
"hookText": "...",
"textStyle": "...",
"textPlacement": "..."
}
]
}
}Pass any concept's prompt straight into POST /thumbnails to generate the image.
Editing
All editing endpoints accept an image URL and return the edited result. Some are free, others cost 1 credit.
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| POST | /thumbnails/edit | General AI edit with prompt | 1 |
| POST | /thumbnails/edit/face-swap | Swap a face onto an image | 1 |
| POST | /thumbnails/edit/background-remove | Remove background (transparent PNG) | Free |
| POST | /thumbnails/edit/background-replace | Replace background with new scene | 1 |
| POST | /thumbnails/edit/color-enhance | Apply color grading preset | Free |
| POST | /thumbnails/edit/upscale | Upscale image 2x or 4x | Free |
| POST | /thumbnails/edit/filter | Apply visual style/filter | Free |
| POST | /thumbnails/edit/combine | Combine two images into one | 1 |
Edit Endpoint Details
General Edit (POST /thumbnails/edit)
{
"imageUrl": "https://...",
"prompt": "Change the sky to a sunset",
"referenceImageUrls": ["https://..."],
"aspectRatio": "16:9"
}Face Swap (POST /thumbnails/edit/face-swap)
Provide either faceImageUrl (a direct URL) or faceId (a saved face ID):
{
"imageUrl": "https://...",
"faceImageUrl": "https://..."
}Background Remove (POST /thumbnails/edit/background-remove)
{
"imageUrl": "https://..."
}Background Replace (POST /thumbnails/edit/background-replace)
{
"imageUrl": "https://...",
"backgroundPrompt": "tropical beach at sunset",
"aspectRatio": "16:9"
}Color Enhance (POST /thumbnails/edit/color-enhance)
Presets: vibrant, dramatic, warm, cool, high-contrast, cinematic
{
"imageUrl": "https://...",
"preset": "cinematic",
"intensity": "medium"
}Upscale (POST /thumbnails/edit/upscale)
{
"imageUrl": "https://...",
"scale": "2x"
}Filter (POST /thumbnails/edit/filter)
{
"imageUrl": "https://...",
"filterPrompt": "oil painting style"
}Combine (POST /thumbnails/edit/combine)
{
"imageUrl1": "https://...",
"imageUrl2": "https://...",
"prompt": "Place the person from image 2 into image 1",
"aspectRatio": "16:9"
}Edit Response Format
All editing endpoints return the same structure:
{
"data": {
"id": "uuid",
"imageUrl": "https://...",
"prompt": "...",
"creditsCost": 1
}
}Utilities
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| POST | /thumbnails/critique | AI critique with scores and suggestions | 1 |
| POST | /thumbnails/optimize | Optimize idea into viral thumbnail | 1 |
| POST | /thumbnails/analyze/text-overlay | Get text overlay suggestions | Free |
| POST | /thumbnails/extract-youtube | Extract YouTube video thumbnail | Free |
Utility Endpoint Details
Critique Thumbnail (POST /thumbnails/critique)
Returns scores across 7 dimensions (contrast, composition, text readability, face visibility, color appeal, clickability, emotional impact), strengths, weaknesses, actionable improvements, and an attention heatmap.
{
"imageUrl": "https://...",
"niche": "gaming"
}Response:
{
"data": {
"overallScore": 72,
"scores": {
"contrast": 8,
"composition": 7,
"textReadability": 6,
"faceVisibility": 9,
"colorAppeal": 7,
"clickability": 8,
"emotionalImpact": 7
},
"strengths": ["Strong facial expression", "Good color contrast"],
"weaknesses": ["Text too small for mobile", "Background too busy"],
"improvements": ["Increase text size by 30%", "Darken background"],
"attentionAreas": [
{ "x": 50, "y": 40, "radius": 20, "intensity": 0.9, "label": "Face" }
],
"summary": "Strong emotional impact but text readability needs improvement.",
"creditsCost": 1
}
}Optimize & Generate (POST /thumbnails/optimize)
Takes a rough idea, uses AI to analyze and create a viral-optimized prompt, then generates the thumbnail.
{
"idea": "a cooking tutorial about making pasta from scratch",
"collectionId": "uuid"
}Text Overlay Suggestions (POST /thumbnails/analyze/text-overlay)
Analyzes a thumbnail and suggests what text to add, where to place it, colors, fonts, and styling for maximum CTR.
{
"imageUrl": "https://...",
"originalPrompt": "Excited chef in a kitchen",
"faceName": "Gordon"
}Extract YouTube Thumbnail (POST /thumbnails/extract-youtube)
Extracts the existing thumbnail from a YouTube video at the highest available quality (maxres > high > medium > standard).
{
"youtubeUrl": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
}Faces
| Method | Endpoint | Description |
|---|---|---|
| GET | /faces | List faces |
| POST | /faces | Create a face |
| GET | /faces/{id} | Get face details |
| PATCH | /faces/{id} | Update a face |
| DELETE | /faces/{id} | Delete a face |
| POST | /faces/upload-urls | Get presigned upload URLs |
Styles
| Method | Endpoint | Description |
|---|---|---|
| GET | /styles | List styles |
| POST | /styles | Create a style |
| GET | /styles/{id} | Get style details |
| PATCH | /styles/{id} | Update a style |
| DELETE | /styles/{id} | Delete a style |
Brands
| Method | Endpoint | Description |
|---|---|---|
| GET | /brands | List brands |
| POST | /brands | Create a brand |
| GET | /brands/{id} | Get brand details |
| PATCH | /brands/{id} | Update a brand |
| DELETE | /brands/{id} | Delete a brand |
Collections
| Method | Endpoint | Description |
|---|---|---|
| GET | /collections | List collections |
| POST | /collections | Create a collection |
| GET | /collections/{id} | Get collection with thumbnails |
| PATCH | /collections/{id} | Update a collection |
| DELETE | /collections/{id} | Delete a collection |
| POST | /collections/{id}/thumbnails | Add thumbnail to collection |
| DELETE | /collections/{id}/thumbnails | Remove thumbnail from collection |
SEO
| Method | Endpoint | Description |
|---|---|---|
| POST | /seo/titles | Generate video titles |
| POST | /seo/description | Generate video description |
Templates
| Method | Endpoint | Description | Credits |
|---|---|---|---|
| GET | /templates | List templates | - |
| POST | /templates/{id}/remix | Remix a template | 1 |
Uploads
| Method | Endpoint | Description |
|---|---|---|
| POST | /uploads/presigned-url | Get presigned upload URL |
Common Parameters
Pagination
All list endpoints support pagination:
page- Page number (default: 1)limit- Items per page (default: 20, max: 100)
Response Format
All responses follow this structure:
Success:
{
"data": { ... }
}Paginated:
{
"data": [ ... ],
"pagination": {
"page": 1,
"limit": 20,
"total": 100,
"hasMore": true
}
}Error:
{
"error": "Error message",
"code": "ERROR_CODE",
"details": { ... }
}HTTP Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 201 | Created |
| 400 | Bad Request - Invalid input |
| 401 | Unauthorized - Invalid API key |
| 402 | Payment Required - Insufficient credits |
| 403 | Forbidden - Quota exceeded |
| 404 | Not Found |
| 429 | Too Many Requests - Rate limited |
| 500 | Internal Server Error |