Vugola API
Clip long videos into short-form shorts, add captions, and schedule posts to 8 social platforms, all programmatically. REST over HTTPS, Bearer authentication.
Introduction
The Vugola API lets you build AI video clipping into your own apps, agents, and workflows. You send a long-form video URL, Vugola returns multiple short-form clips with AI-generated titles and virality scores. You can also schedule clips to post on X, Instagram, TikTok, YouTube, Facebook, LinkedIn, Threads, and Bluesky from the same API.
Base URL:
https://www.vugolaai.com/api/v1Agent-friendly from day one. The same endpoints are available as MCP tools through our official server at vugola-mcp on npm. One command in Claude Desktop, Claude Code, Cursor, or Cline. see MCP server.
Quickstart
Three steps: get a key, check your credits, start a clipping job.
1. Get an API key
Visit vugolaai.com/dashboard/api-key while signed in. Keys are prefixed vug_sk_. API access is available on every paid plan (Starter, Creator, and Agency).
2. Check your credits
Sanity-check that the key is valid:
curl https://www.vugolaai.com/api/v1/status \
-H "Authorization: Bearer $VUGOLA_API_KEY"Returns your plan name and remaining credits. One credit = one minute of source video.
3. Clip a video
Kick off a clipping job:
curl https://www.vugolaai.com/api/v1/clip \
-H "Authorization: Bearer $VUGOLA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://www.youtube.com/watch?v=VIDEO_ID",
"aspect_ratio": "9:16",
"caption_style": "minimalist"
}'You get back a job_id immediately. Poll GET /clip/:job_id every 30–60 seconds. Most jobs complete in 10–30 minutes. Vugola also emails you when clips are ready.
Authentication
Every request needs a Bearer token in the Authorization header.
Authorization: Bearer vug_sk_your_key_hereKeys are tied to a single Vugola account. Never commit them to a public repo. GitHub secret scanning watches the vug_sk_ prefix. To rotate, generate a new key at /dashboard/api-key and delete the old one.
Free accounts without an active paid subscription receive a 403 subscription_required response with an upgrade_url in the body pointing at /dashboard/subscription.
Rate limits & plans
Per-account limits are enforced by the API layer. Hitting them returns 429 Too Many Requests.
| Field | Type | Required | Description |
|---|---|---|---|
Clipping requests | 5 / minute | optional | POST /clip can be called up to 5 times per minute per account. |
Concurrent jobs | 3 | optional | A maximum of 3 clipping jobs can be processing at once per account. |
Failed clip requests | 20 / hour | optional | If you send 20 failing clipping requests in an hour, further clip requests are blocked until the window resets. Scheduling and read endpoints aren't affected. |
Auth failures | 10 / minute | optional | Repeated invalid-key attempts on the same prefix are rate-limited. |
Scheduled posts (Starter) | 10 / month | optional | Starter-tier accounts using the scheduling API are limited to 10 posts per calendar month. |
Credits themselves are not a rate limit. they reset with your billing cycle. Clipping cost is calculated at job completion as max(1, ceil(video_minutes)), so a 5:30 video consumes 6 credits.
Errors
Errors are returned as JSON with error (a stable code you can branch on) and message (a human-readable string).
| Field | Type | Required | Description |
|---|---|---|---|
400 | bad_request | optional | Invalid request body. Common codes: invalid_aspect_ratio, invalid_caption_style, invalid_caption_color, video_too_short (<5 min), video_too_long (>2 h), unknown_duration, blocked_url, missing_video_url, x_reconnect_required. A scheduled_at value in the past also returns 400 with a human-readable message. |
401 | invalid_api_key / api_key_revoked / account_not_found | optional | Missing or malformed Authorization header, revoked key, or the account associated with the key has been deleted. |
402 | insufficient_credits | optional | Not enough credits to start the job. Response body includes credits_remaining, credits_needed, and upgrade_url. |
403 | subscription_required | optional | Your Vugola account has no active paid subscription. Response includes upgrade_url pointing to /dashboard/subscription. |
404 | not_found | optional | Job or scheduled post doesn't exist, or isn't owned by the authenticated account. |
409 | cannot_cancel | optional | Attempting to DELETE a scheduled post whose status is no longer 'scheduled' (already processing or posted). |
429 | rate_limit | optional | Per-account rate limit hit. Honor the Retry-After header if present. |
500 | server_error | optional | Temporary server error. Safe to retry idempotent GETs. Do NOT retry POSTs without idempotency. duplicate-charge risk. |
All user-supplied URLs (for video_url and media_url) are SSRF-protected server-side: no private IP ranges, no cloud metadata endpoints, no file://.
Clipping
Turn a long-form video into multiple short-form clips with AI-generated titles, virality scores, and captions. Jobs are asynchronous.
Start a clipping job
/clip| Field | Type | Required | Description |
|---|---|---|---|
video_url | string | required | Public video URL. YouTube, Vimeo, or direct MP4. Must be 5 minutes to 2 hours long. |
aspect_ratio | string enum | required | "9:16", "16:9", or "1:1". |
caption_style | string enum | required | "none", "highlighted", "scale", "minimalist", "box", "staticbox", "glow", or "hormozi". |
caption_color | string hex | optional | Caption highlight color. Format #RRGGBB, e.g. #FFE600. |
Example request:
curl https://www.vugolaai.com/api/v1/clip \
-H "Authorization: Bearer $VUGOLA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://www.youtube.com/watch?v=VIDEO_ID",
"aspect_ratio": "9:16",
"caption_style": "minimalist",
"caption_color": "#FFE600"
}'Response (202 Accepted):
{
"job_id": "c2c0205e-d5e9-47e0-8328-127c05de1b4e",
"status": "processing",
"message": "Video is being processed. Poll GET /clip/:job_id for status."
}If you submit the same video_url + aspect_ratio + caption_style while a recent job for that combination is still in flight or already completed, the API returns the existing job and includes "duplicate": true in the response. no extra credits are charged.
Check job status
/clip/:job_idReturns one of three status values: processing, complete, or failed. Poll every 30–60 seconds.
curl https://www.vugolaai.com/api/v1/clip/c2c0205e-... \
-H "Authorization: Bearer $VUGOLA_API_KEY"While processing:
{
"job_id": "c2c0205e-...",
"status": "processing",
"mode": "clipping",
"progress": 45,
"clips_ready": 2,
"clips_total": 5
}When complete:
{
"job_id": "c2c0205e-...",
"status": "complete",
"mode": "clipping",
"credits_used": 8,
"clips": [
{
"clip_id": "uuid",
"title": "The moment X happened",
"duration": 42.5,
"virality_score": 0.92,
"download_url": "https://<storage>.supabase.co/.../clip-1.mp4?token=..."
}
],
"download_endpoint": "https://www.vugolaai.com/api/v1/clip/c2c0205e-.../download/all"
}When failed:
{
"job_id": "c2c0205e-...",
"status": "failed",
"mode": "clipping",
"error": "Upstream transcription failed"
}mode is clipping for POST /clip jobs and captions for POST /caption jobs. duration is seconds (float). virality_score is a 0–1 float (higher is better). Each download_url is a presigned link for clips rendered after 2026-04-15. open it in a browser without any headers, valid for roughly one hour. Older clips fall back to an authenticated proxy URL that does require the Authorization header.
Get all clip download URLs
/clip/:job_id/download/allReturns every rendered clip for a completed job. Each download_url is a presigned link that works directly in a browser (no Authorization header required) and expires after roughly one hour. Save clips promptly or re-fetch this endpoint to refresh the links.
{
"job_id": "c2c0205e-...",
"clips": [
{
"clip_index": 1,
"clip_id": "uuid",
"title": "The moment X happened",
"filename": "1-the-moment-x-happened.mp4",
"virality_score": 0.92,
"duration": 42.5,
"download_url": "https://<storage>.supabase.co/.../clip-1.mp4?token=..."
}
],
"note": "download_url is a presigned link valid for approximately 1 hour. No Authorization header required."
}Download a specific clip
/clip/:job_id/download/:clip_indexStreams the clip directly as video/mp4. clip_index is 1-based.
curl https://www.vugolaai.com/api/v1/clip/c2c0205e-.../download/1 \
-H "Authorization: Bearer $VUGOLA_API_KEY" \
-o clip-1.mp4Captions
Add captions to a short video (up to 5 minutes) without clipping, moment-finding, or reframing. The source video is preserved at original quality and dimensions. only captions are burned on top. Uses the same Remotion caption styles available in the Vugola dashboard.
Add captions to a video
/caption| Field | Type | Required | Description |
|---|---|---|---|
video_url | string | required | Public video URL. YouTube, Vimeo, or direct MP4. Max 5 minutes. |
aspect_ratio | string enum | required | "9:16", "16:9", or "1:1". Controls caption positioning. does NOT reframe the video. |
caption_style | string enum | required | "none", "highlighted", "scale", "minimalist", "box", "staticbox", "glow", or "hormozi". |
caption_color | string hex | optional | Caption highlight color. Format #RRGGBB. |
Example request:
curl https://www.vugolaai.com/api/v1/caption \
-H "Authorization: Bearer $VUGOLA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"video_url": "https://www.youtube.com/watch?v=VIDEO_ID",
"aspect_ratio": "9:16",
"caption_style": "minimalist"
}'Response (202 Accepted):
{
"job_id": "uuid",
"status": "processing",
"mode": "captions",
"message": "Video is being captioned. Poll GET /clip/:job_id for status."
}Caption jobs share the same status endpoint as clip jobs: GET /clip/:job_id. The response includes mode: "captions" so clients can distinguish. When complete, clips[] contains one item. the full captioned video. Credits: 1 per minute of source video, refunded automatically if no speech is detected.
No-speech error: If the video has no spoken audio, the job fails immediately after transcription (~30–60 seconds) with error no_speech_detected. Credits are automatically refunded.
Scheduling
Queue posts to up to 8 social platforms in a single request. Supported platforms: x, instagram, tiktok, youtube, facebook, linkedin, threads, bluesky.
Schedule posts
/scheduleSend up to 25 posts per request.
| Field | Type | Required | Description |
|---|---|---|---|
posts | array | required | Non-empty array, max 25 items. Each item is a post object. |
posts[].platform | string enum | required | One of the 8 supported platform strings. |
posts[].caption | string | required | Post caption. Max 5000 characters. (Platforms apply their own stricter limits at post-time.) |
posts[].scheduled_at | ISO 8601 | required | Future UTC timestamp. |
posts[].media_url | string URL | optional | Publicly reachable URL. Required for single posts on Instagram, TikTok, YouTube. Downloaded and re-uploaded to Vugola storage before posting. |
posts[].asset_id | uuid | optional | Alternative to media_url when the media is already uploaded to your Vugola asset library. |
posts[].title | string | optional | Max 200 characters. Used by YouTube. |
posts[].platform_settings | object | optional | Free-form platform-specific options (e.g., YouTube category, TikTok privacy). |
Example request:
curl https://www.vugolaai.com/api/v1/schedule \
-H "Authorization: Bearer $VUGOLA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"posts": [
{
"platform": "tiktok",
"caption": "My caption",
"scheduled_at": "2026-05-01T15:00:00.000Z",
"media_url": "https://cdn.example.com/clip.mp4"
}
]
}'Response (201):
{
"success": true,
"posts": [
{
"id": "uuid",
"platform": "tiktok",
"status": "scheduled",
"scheduled_at": "2026-05-01T15:00:00.000Z"
}
]
}List scheduled posts
/scheduleOptional query parameters: status (scheduled, processing, posted, failed, cancelled), platform, limit (default 20, max 100), offset (default 0).
{
"posts": [
{
"id": "uuid",
"platform": "tiktok",
"caption": "My caption",
"title": null,
"status": "scheduled",
"scheduled_at": "2026-05-01T15:00:00.000Z",
"posted_at": null,
"failure_reason": null
}
],
"total": 42,
"limit": 20,
"offset": 0
}Get one scheduled post
/schedule/:post_idReturns the full record for a single post. Useful for checking whether a post has gone live or failed with a reason.
{
"id": "uuid",
"platform": "tiktok",
"caption": "My caption",
"title": null,
"status": "posted",
"scheduled_at": "2026-05-01T15:00:00.000Z",
"posted_at": "2026-05-01T15:00:12.428Z",
"failure_reason": null
}Cancel a scheduled post
/schedule/:post_idOnly posts with status: scheduled can be cancelled. Posts that are already processing or have posted return 409 cannot_cancel.
{
"success": true,
"id": "uuid",
"status": "cancelled"
}Credits
Check balance
/statusMinimal balance check. Safe to call before every job.
{
"credits_remaining": 847,
"credits_total": 1200,
"plan": "agency"
}Usage with monthly breakdown
/usage{
"credits_remaining": 847,
"credits_total": 1200,
"credits_used_this_month": 353,
"plan": "agency"
}Transaction history
/usage/historyPaginated list of credit transactions. Query params: limit (default 20, max 100), offset (default 0).
{
"transactions": [
{
"id": "uuid",
"type": "debit",
"amount": 8,
"date": "2026-04-14T20:14:00Z",
"video_url": "https://www.youtube.com/watch?v=..."
}
],
"total": 42,
"limit": 20,
"offset": 0
}MCP server
Vugola ships an official Model Context Protocol server so AI agents. Claude Desktop, Claude Code, Cursor, Cline, Windsurf. can clip videos, download clips to disk, and manage scheduled posts on your behalf. Published as vugola-mcp on npm. Always pin the version (currently 1.3.1). never install latest.
Claude Desktop . one-command install, auto-edits your config:
npx vugola-mcp@1.3.1 installThe installer prompts for your API key. Fully quit and reopen Claude Desktop to pick up the tools.
Claude Code. one command from your terminal:
claude mcp add vugola -- npx -y vugola-mcp@1.3.1Then export your API key in the same shell: export VUGOLA_API_KEY=vug_sk_…
Cursor / Cline / Windsurf / manual JSON . drop this into the client's MCP config:
{
"mcpServers": {
"vugola": {
"command": "npx",
"args": ["-y", "vugola-mcp@1.3.1"],
"env": { "VUGOLA_API_KEY": "vug_sk_your_key_here" }
}
}
}Eight tools are available to any agent: clip_video, caption_video (≤5-min videos. burn captions only, no clipping), get_clip_status, download_clip (saves a finished clip to the user's Downloads folder), get_usage, schedule_post, list_scheduled_posts, and cancel_scheduled_post.
The MCP server is listed in the official MCP Registry. Full source, changelog, and per-tool reference at github.com/VCoder25/vugola-mcp.
Changelog
2026-04-16. Captions-only endpoint + MCP v1.3.0
- New endpoint:
POST /captionfor adding captions to short videos (max 5 min). - New MCP tool:
caption_video(8th tool). - No-speech detection with automatic credit refund.
- Caption jobs share
GET /clip/:job_idfor status polling (mode: "captions"in response).
2026-04-15. MCP v1.2.1
- Three new MCP tools:
list_scheduled_posts,cancel_scheduled_post, anddownload_clip(saves a finished clip to the user's Downloads folder). download_urlvalues returned by the API are now presigned. clickable in a browser with no Authorization header, valid for ~1 hour.- MCP server listed in the official MCP Registry as
io.github.VCoder25/vugola-mcp.
2026-04-14. v1.0 launch
- Public REST API available at
www.vugolaai.com/api/v1. - Endpoints:
POST /clip,GET /clip/:job_id,GET /status,GET /usage,POST /schedule. - Bearer auth with
vug_sk_-prefixed keys, available on every paid plan (Starter, Creator, Agency). - Official MCP server published as
vugola-mcpon npm.
Questions, bugs, feature requests: join the community.