Use case

Your app sends each user video to one API and gets back up to 20 ranked, reframed and captioned clips with titles, for $0.03 per source minute, falling to $0.02 past 2,000 minutes a month.

API to build your own OpusClip-style clipping app

An 8-minute speech comes back as 4 captioned clips of up to 45 seconds in under 90 seconds, each with a title and a score, for about $0.24.

All use casesUpdated

Clip 1, 22 seconds, with karaoke captions, reframed to the speaker.clip-1.mp4clip-1.jpgclip-1.srtclip-1.vtt

What the API does and what you build

What the API does and what you build
Part of the appclipsdk APIYou build
Getting the video inUpload tickets up to 5 GB, sent from the browserThe upload button. Page links like YouTube are refused, so take files
Finding the momentsUp to 20 clips, each scored 0 to 100 with a one-line reasonNothing
Framing9:16, 1:1, 4:5 or 16:9, following the speakerNothing
Captions3 burned-in presets, plus SRT and VTTYour own styles, from the SRT or VTT
Titles and post captionsOne of each per clip, at most 3 hashtagsAn edit box
Getting results backA signed webhook, 5 attemptsOne route that checks the signature
Accounts, billing, editor, postingNothingAll of it
Keeping the files7 daysA copy of every clip your users keep

See pricing for what each source minute costs.

Three routes and you have the backend

  1. Take the upload

    Your server asks for an upload ticket, and the browser PUTs the file straight to upload_url within 1 hour. Big files never pass through your server.

    app/api/uploads/route.ts
    // Keep it behind your own sign-in: the ticket lets anyone holding it upload to your account
    export async function POST(request: Request) {
      const { filename, size } = await request.json();
    
      const res = await fetch("https://api.clipsdk.com/v1/uploads", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.CLIPSDK_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ filename, size }),
      });
      return Response.json(await res.json(), { status: res.status });
    }
    
    // In the browser: the file goes straight to upload_url, never through your server
    const ticket = await fetch("/api/uploads", {
      method: "POST",
      body: JSON.stringify({ filename: file.name, size: file.size }),
    }).then((res) => res.json());
    await fetch(ticket.upload_url, { method: "PUT", body: file });
  2. Start the job

    Send the ticket's video_url to POST /v1/clips with your webhook_url. Add a user's own brief in prompt, up to 500 characters, if your app asks for one.

    app/api/clips/route.tsTry it
    // app/api/clips/route.ts: keep it behind your own sign-in, it spends your credits
    export async function POST(request: Request) {
      const { videoUrl } = await request.json();
    
      const res = await fetch("https://api.clipsdk.com/v1/clips?wait=0", {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.CLIPSDK_KEY}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          video_url: videoUrl,
          webhook_url: `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}/api/clipsdk-webhook`,
        }),
      });
      return Response.json(await res.json(), { status: res.status });
    }
  3. Take the webhook

    clipsdk POSTs the finished job, signed with HMAC-SHA256. Check the signature against the raw body, reject anything older than 5 minutes, then save the clips by job id.

    app/api/clipsdk-webhook/route.ts
    export async function POST(request: Request) {
      const raw = await request.text();
      const header = request.headers.get("Clipsdk-Signature") ?? "";
      if (!(await verify(raw, header, process.env.CLIPSDK_WEBHOOK_SECRET!))) {
        return new Response("Bad signature", { status: 401 });
      }
    
      // A job can arrive more than once, so save by job id
      const { event, job } = JSON.parse(raw);
      if (event === "job.succeeded") await saveClips(job.id, job.result.clips);
      return new Response("ok");
    }
    
    async function verify(raw: string, header: string, secret: string) {
      const { t, v1 = "" } = Object.fromEntries(header.split(",").map((part) => part.split("=")));
      if (!t || !/^[0-9a-f]{64}$/.test(v1) || Math.abs(Date.now() / 1000 - Number(t)) > 300) return false;
    
      const encoder = new TextEncoder();
      const key = await crypto.subtle.importKey("raw", encoder.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["verify"]);
      const signature = Uint8Array.from(v1.match(/../g)!, (byte) => parseInt(byte, 16));
      return crypto.subtle.verify("HMAC", key, signature, encoder.encode(`${t}.${raw}`));
    }

The request behind the clip

This is the exact request behind the clip above. Your app sends the same body with its own video_url and a webhook_url.

POST/v1/clipsTry it
curl https://api.clipsdk.com/v1/clips \
  -H "Authorization: Bearer $CLIPSDK_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "video_url": "https://api.clipsdk.com/f/lib/demo/artemis-moon-speech.mp4",
    "clips": 4,
    "max_seconds": 45,
    "aspect": "9:16",
    "reframe": "auto",
    "captions": "karaoke"
  }'

What you skip building

A clipping app needs a transcript, a way to find the moments worth posting, a crop that follows the speaker and captions burned into the video. That is the one call. Each clip comes back as an MP4 with a poster, SRT and VTT files, a title, a post caption and a score with its reason.

What stays yours is everything users touch: sign-up, billing, the editor, posting to TikTok or YouTube, and storage. If 3 caption presets are not enough, turn burned-in captions off and draw your own from the SRT or VTT.

Pricing your app per source minute

You pay $0.03 per source minute, and $0.02 for every minute past 2,000 in a month. For a source up to 1080p60 and 20 Mb/s, the number of clips doesn't change the price, and failed jobs cost nothing, so you can charge your users per minute or per video and know your cost.

New accounts get $1 free, 33 minutes, enough to build and test the whole flow.

  • 50 hours of user video a month: $80 (2,000 min at $0.03 and 1,000 at $0.02)
  • 500 hours of user video a month: $620 (2,000 min at $0.03 and 28,000 at $0.02)
  • 1,000 hours of user video a month: $1,220 (2,000 min at $0.03 and 58,000 at $0.02)

Limits to design around

An account runs 3 jobs at once and 200 a day, with 20 GB of uploads a day, across all its keys. Queue user jobs on your side, and when the API answers 429, wait for Retry-After. Keep $5.40 of credit for each job you run at once: until clipsdk has checked a video's length, its job holds up to that much, and a job that finds less than $0.03 free gets 402 INSUFFICIENT_CREDIT. Email us before launch and we raise the limits for your volume.

Send an Idempotency-Key with each job, so a retry after a timeout never starts or bills a second one. Uploads and webhooks cover every field.

Building with Lovable, Bolt or a coding agent

Integrations has a ready prompt for Lovable and for Bolt, and the job route as a Supabase Edge Function. The webhook check above is plain Web Crypto, so it runs the same in an Edge Function or a Cloudflare Worker.

Working in Claude Code, Cursor or VS Code? Add our hosted MCP server at https://mcp.clipsdk.com/mcp with your key, or run clipsdk-mcp, the open-source local one, on Node 20 or later, which saves the clips into your project. Either gives the agent 3 tools (create_clips, get_job, plus create_upload or upload_file), so you can try settings on real videos before you write a route.

Questions, answered

Can I build an OpusClip-style app on clipsdk?

Yes. clipsdk does the transcript, the ranking, the speaker crop and the captions in one call. You build the app around it: accounts, billing, an editor and posting.

How much does it cost per user video?

$0.03 per source minute, $0.02 past 2,000 minutes a month, every clip included up to 1080p60 and 20 Mb/s. A 30 minute video costs $0.90, and 500 hours of user video in a month costs $620.

Can users paste YouTube links into my app?

No. clipsdk refuses YouTube, Twitch and other page links. Take file uploads, or send a direct link to a file you host.

Is there an MCP server for clipsdk?

Yes, two. The hosted one at https://mcp.clipsdk.com/mcp takes your API key as a Bearer header and gives Claude Code, Cursor, VS Code and other MCP clients 3 tools: create_clips, get_job and create_upload. clipsdk-mcp is open source under the MIT license, runs locally with Node 20 or later and has upload_file in place of create_upload.

Can I sell the clips under my own brand?

Yes. Clips carry no watermark and nothing that names clipsdk, and your users only ever see your app.

Start free

Your back catalog is full of shorts

Your first $1 is free: 33 minutes of video, every clip included up to 1080p60 and 20 Mb/s.

Two studio microphones on a desk in a dark room lit by a red glow