Vugola API
Clip long videos into short-form shorts, add captions, manage hands-free channel Automations, and schedule posts to five live destinations, all programmatically. Posting is currently live for TikTok, YouTube, X, LinkedIn, and Bluesky. Instagram, Facebook, and Threads are temporarily unavailable. 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 captions. You can also watch YouTube channels and automatically clip new uploads, then schedule clips to post on X, TikTok, YouTube, LinkedIn, and Bluesky from the same API. Instagram, Facebook, and Threads are temporarily unavailable.
Base URL:
https://www.vugolaai.com/api/v1Agent-friendly from day one. Core clipping, scheduling, and Automation workflows are available as MCP tools through our official OAuth server at https://www.vugolaai.com/api/mcp. Sign in with Vugola; no API key is required. 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 with an active paid plan.
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. Clipping and captions show an exact quote based on source duration and processing cost before the job starts.
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.
Accounts without an active paid plan 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. |
Credits themselves are not a rate limit. They reset with your billing cycle. Clipping and caption jobs are quoted from source duration and processing cost. The API preflight and completed-job charge use the same locked quote.
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 (>3 h), unknown_duration, video_unavailable (source is private, region-locked, or unsupported), blocked_url, missing_video_url, x_reconnect_required. A scheduled_at value in the past also returns 400 with a human-readable message. |
400 | live_source | optional | The video is still broadcasting, is a scheduled premiere, or just ended and the replay is not published yet. Submit it again once the broadcast has finished; no credits are charged. |
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 plan. 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. |
503 | usage_unavailable | optional | Credit usage or history could not be read temporarily. Safe to retry GET /usage or GET /usage/history. |
503 | source_temporarily_blocked | optional | The video source temporarily blocked our download (e.g. rate/bot check). Transient, NOT a length problem. retry in a few minutes (retry_after_minutes in the body). No credits are charged. |
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 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 3 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",
"credit_quote": { "credits": 238, "billable_seconds": 600 },
"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.
credit_quote.credits is the exact locked charge for a successfully completed job. This 600-second example is quoted at 238 credits; the value returned for your request is authoritative. Output clip count adds no charge, and the locked value cannot increase after acceptance. A documented refund can reduce the net charge after failure.
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,
"source_title": "How I bootstrapped to $1M ARR",
"aspect_ratio": "9:16",
"caption_style": "hormozi",
"clips": [
{
"clip_id": "uuid",
"title": "The moment X happened",
"duration": 42.5,
"download_url": "https://www.vugolaai.com/api/v1/clip/c2c0205e-.../download/1?download_token=...",
"preview_url": "https://www.vugolaai.com/api/v1/clip/c2c0205e-.../download/1?download_token=...&inline=1",
"thumbnail_url": "https://www.vugolaai.com/api/v1/clip/c2c0205e-.../thumbnail/1?download_token=..."
}
]
}When complete:
{
"job_id": "c2c0205e-...",
"status": "complete",
"mode": "clipping",
"credits_used": 238,
"clips_ready": 5,
"clips_total": 5,
"source_title": "How I bootstrapped to $1M ARR",
"aspect_ratio": "9:16",
"caption_style": "hormozi",
"clips": [
{
"clip_id": "uuid",
"title": "The moment X happened",
"duration": 42.5,
"download_url": "https://www.vugolaai.com/api/v1/clip/c2c0205e-.../download/1?download_token=...",
"preview_url": "https://www.vugolaai.com/api/v1/clip/c2c0205e-.../download/1?download_token=...&inline=1",
"thumbnail_url": "https://www.vugolaai.com/api/v1/clip/c2c0205e-.../thumbnail/1?download_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). clips are returned in Vugola's own ranked order. Each download_url is a one-hour Vugola-signed delivery link. Open it in a browser without any headers. The link stays bound to the exact clip and only confirms delivery after the complete file is streamed. clips_total counts every attempted clip and is null until the first clip job exists; a complete job can still show clips_ready lower than clips_total when a clip failed. source_title is the video's title or uploaded filename, and may be null. preview_url plays inline in a browser, is scrubbable, and is never counted as a download. thumbnail_url is the clip's poster frame, and is null until one exists.
Get all clip download URLs
/clip/:job_id/download/allReturns every rendered clip for a completed job. Each download_url is a Vugola-signed delivery 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",
"duration": 42.5,
"download_url": "https://www.vugolaai.com/api/v1/clip/c2c0205e-.../download/1?download_token=..."
}
],
"note": "download_url is a Vugola-signed delivery 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 video (up to 20 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 20 minutes; there is no minimum duration. |
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",
"credit_quote": { "credits": 24, "billable_seconds": 60 },
"message": "Video is being processed. 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. The 202 response returns the exact locked processing-cost quote. Credits are 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.
Automations
Automations watch a YouTube channel for eligible new uploads, create clips with your chosen output settings, and schedule those clips to connected social accounts. They are available to Creator and Agency workspace owners. Creator includes one Automation; Agency includes up to five.
Call GET /automations/destinations first and use the returned connection IDs. Do not infer an account from its platform name. Instagram, Facebook, and Threads are temporarily unavailable as Automation destinations.
List available destinations
/automations/destinations{
"destinations": [
{
"id": "connection-uuid",
"platform": "youtube",
"account_handle": "@creator",
"status": "active",
"available_for_automations": true
}
]
}Create an Automation
/automations| Field | Type | Required | Description |
|---|---|---|---|
channel_url | string | required | YouTube channel, video, youtu.be, or @handle URL. |
destination_connection_ids | uuid[] | required | One or more IDs returned by GET /automations/destinations. |
aspect_ratio | string enum | optional | "9:16" (default), "1:1", or "16:9". |
caption_style | string enum | optional | Same values as clipping. Defaults to "hormozi". |
post_caption_enabled | boolean | optional | Defaults true. YouTube still receives an AI-generated title when false. |
posting_times | string[] | optional | One to five local HH:MM times. Defaults to ["09:00", "13:00"]. |
timezone | string | optional | IANA timezone. Defaults to the workspace timezone. |
curl https://www.vugolaai.com/api/v1/automations \
-H "Authorization: Bearer $VUGOLA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"channel_url": "https://www.youtube.com/@MoreMozi",
"destination_connection_ids": ["connection-uuid"],
"aspect_ratio": "9:16",
"caption_style": "hormozi",
"posting_times": ["09:00", "13:00"],
"timezone": "America/Chicago"
}'Inspect and manage
GET /automations
GET /automations/{automation_id}
PATCH /automations/{automation_id}
POST /automations/{automation_id}/pause
POST /automations/{automation_id}/resume
DELETE /automations/{automation_id}The detail endpoint includes recent source videos and runs plus draft, scheduled, and posted clip counts. Posts created after an update use the new settings; already-scheduled posts are unchanged. Pausing does not cancel already-scheduled posts. Deleting is destructive and cancels pending draft or scheduled posts for that Automation.
Scheduling
The API enum contains eight platform integrations. Posting is currently live for x, tiktok, youtube, linkedin, and bluesky. Instagram, Facebook, and Threads are temporarily unavailable. The complete enum is: 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 integration strings. Five destinations are currently live; Instagram, Facebook, and Threads are temporarily unavailable. |
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",
"account": { "platform": "tiktok", "handle": "itzvadims", "name": "Vadim", "avatar_url": null },
"media": null
}
]
}account is the connected account the post will publish from (handle has no leading @); media is present only when media_url was a Vugola clip link. media is null otherwise. When media_url is a Vugola clip link, media is { "source_clip_job_id", "thumbnail_url", "preview_url" } (thumbnail_url is null until the clip has a poster frame).
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",
"platform": "tiktok",
"scheduled_at": "2026-05-01T15:00:00.000Z"
}Credits
Check balance
/statusMinimal balance check. Safe to call before every job.
{
"credits_remaining": 8470,
"credits_total": 12000,
"plan": "agency"
}Usage with monthly breakdown
/usageUsage counts from your last credit reset (your plan's renewal date) and nets out refunds, so used plus remaining always equals your total.
{
"credits_remaining": 8470,
"credits_total": 12000,
"credits_used_this_month": 3530,
"plan": "agency"
}Transaction history
/usage/historyPaginated list of credit transactions. Query params: limit (default 20, max 100), offset (default 0).
{
"transactions": [
{
"id": "uuid",
"type": "transcription_minute",
"amount": 80,
"date": "2026-08-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 and channel Automations on your behalf. The OAuth server is available at https://www.vugolaai.com/api/mcp. Sign in with Vugola; no API key is required.
Local npm option — original 8 tools . the original clip and scheduling tools are also published as vugola-mcp. Use the OAuth server above when you need Automations. Pin the current version; never install latest:
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" }
}
}
}Seventeen tools are available through the OAuth MCP: 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; plus list_automation_destinations, resolve_automation_channel, create_automation, list_automations, get_automation, update_automation, pause_automation, resume_automation, and delete_automation.
The MCP server is listed in the official MCP Registry. Local npm server source, changelog, and original eight-tool reference at github.com/VCoder25/vugola-mcp.
Prefer Claude Code? Download the Vugola skill and unzip it into your Claude Code skills folder. It bundles the SKILL.md, FAQ, and full API reference so Claude knows how to clip, caption, and schedule without you pasting docs.
Download Claude Code skillChangelog
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 with an active paid plan. - Official MCP server published as
vugola-mcpon npm.
Questions, bugs, feature requests: join the community.