Skip to main content
Video Clipping is the repurposing primitive for turning long-form video into short-form content. Submit a video URL (a direct file or a YouTube link) and a worker transcribes it, scores the most engaging segments, cuts them into clips, burns in captions, and — by default — reframes them to vertical 9:16. All jobs go through the unified jobs system, and credits are metered on the true actuals at completion.

CLI First

# Auto-clip a long video (async — returns a job id). Vertical 9:16 by default.
naive video clip "https://example.com/podcast.mp4" --wait

# Keep the original 16:9 aspect
naive video clip "https://youtube.com/watch?v=abc123" --aspect 16:9 --wait

# Check status of a clip job
naive video clip-status job-uuid-123

Tools

ToolTypeDescriptionCost
naive_create_clipsCoreSubmit a video for auto-clipping (async)Metered per input minute
naive_clips_statusCoreCheck a clip job’s statusFree

Creating clips

POST /v1/video/clip submits a video for clipping. The only required field is video_url — a public https URL to a video no longer than 90 minutes (a direct file or a supported host such as YouTube).
curl -X POST https://api.usenaive.ai/v1/video/clip \
  -H "Authorization: Bearer nv_sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "video_url": "https://example.com/podcast.mp4",
    "aspect_ratio": "9:16",
    "remove_silence": false
  }'
const response = await fetch("https://api.usenaive.ai/v1/video/clip", {
  method: "POST",
  headers: {
    "Authorization": "Bearer nv_sk_your_key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    video_url: "https://example.com/podcast.mp4",
    aspect_ratio: "9:16",
    remove_silence: false,
  }),
});
const job = await response.json();
Response (202):
{
  "job_id": "job-uuid",
  "status": "queued",
  "message": "Clip job queued"
}

Parameters

ParamTypeRequiredDefaultDescription
video_urlstringYesPublic https URL to a video (≤ 90 min). Direct file or YouTube.
aspect_ratiostringNo"9:16"Output ratio: "9:16" (vertical, face-tracked reframe) or "16:9" (keep original)
remove_silencebooleanNofalseTrim silences from each clip (adds a small per-clip surcharge)
Only one clip job may be in flight per account at a time. YouTube-source jobs also have a rolling 24-hour bandwidth ceiling to bound proxy cost.

Polling for completion

Clip extraction takes several minutes. Poll the job:
curl https://api.usenaive.ai/v1/video/clip/job-uuid \
  -H "Authorization: Bearer nv_sk_your_key"
const response = await fetch("https://api.usenaive.ai/v1/video/clip/job-uuid", {
  headers: { "Authorization": "Bearer nv_sk_your_key" },
});
const status = await response.json();
Response (completed):
{
  "status": "completed",
  "result": {
    "clips": [
      {
        "title": "The Secret to Scaling",
        "url": "https://.../clip-1.mp4",
        "score": 87
      }
    ]
  },
  "credits_used": 0.84
}
Each finished clip is auto-ingested into your Media Asset Manager with source_type: "video_clipping". Use naive media list --source video_clipping or GET /v1/media?source_type=video_clipping to find them.

Cost

Clipping is metered, not a flat fee — the charge is derived entirely server-side from the true actuals of each job (transcribed audio minutes, scoring tokens, clip count, optional silence-removal and 9:16 reframe compute, and — for YouTube sources — proxy bandwidth). Credits are charged on completion only; failed or cancelled jobs cost nothing. A short direct-file clip settles for a fraction of a credit; a long YouTube source with reframing settles higher. Preview the pricing band with GET /v1/video/pricing.

Error handling

ErrorCauseRecovery
invalid_inputMissing/invalid video_url or bad aspect_ratio/remove_silenceProvide a public https video_url; aspect_ratio must be "9:16" or "16:9"
insufficient_creditsNot enough credits for the provisional holdTop up with naive billing topup
rate_limitedDaily YouTube proxy-bandwidth ceiling reachedRetry after 24h, or use a direct file URL (no proxy)
provider_errorUpstream transcription/processing failedCheck the video URL and try again

Typical workflow

Agent task: "Turn this podcast into vertical Shorts"
    |
    +-- POST /v1/video/clip                       --> Submit video_url (9:16 default)
    |   --> job_id: job-uuid, status: queued
    |
    +-- GET /v1/video/clip/job-uuid               --> Poll every 30-60s
    |   --> status: queued -> completed
    |   --> clips[] ranked by score
    |
    +-- GET /v1/media?source_type=video_clipping  --> Auto-ingested to Media Assets
    |
    +-- POST /v1/social/posts                      --> Distribute the top clips