# FastClip API Documentation > Endpoints, pricing, limits, and code examples for integrating the FastClip video clipping API. --- ## What is FastClip? FastClip is a **video clipping API**. You give it a video URL and timestamps; it downloads the source, trims the segment, and returns a download link - all via a simple REST API or a web interface at fastclip.dev. It also has an **AI Auto-Clip** mode: describe what you want to clip in plain English and the AI finds matching moments automatically. --- ## Supported Platforms | Platform | Domains | |----------------|--------------------------------------------------| | YouTube | youtube.com, youtu.be, youtube-nocookie.com | Only YouTube URLs are accepted right now. Other domains currently return HTTP `422`. **Coming soon:** TikTok, X (Twitter), Vimeo, Instagram, Twitch, Kick. --- ## Pricing FastClip is **pay-as-you-go**. No subscriptions. Deposit funds, pay per clip. | Operation | Cost | |-----------------------------|-----------------------------------| | Manual clip | **$0.10** flat per clip (**$0.20** when true 4K MP4 is delivered) | | AI auto-clip | **$0.20 per hour** of source video (rounded up to nearest hour) + **$0.10 flat** when true 4K MP4 is delivered | | AI analyze-only | **$0.10 per hour** of source video (rounded up) | | Extra segment (auto-clip) | **+$0.10** per additional matching segment beyond the first | | Full video download | **$0.05** flat per download (**$0.10** when true 4K MP4 is delivered) | | Transcript | **$0.02** flat per video | **Minimum deposit:** $5.00 **Sign-up credit:** $5.00 free after email verification (no credit card required) Cost is reserved upfront. For auto-clip, any unused reservation is automatically refunded after processing completes (or if the job fails). 4K pricing is based on the quality actually delivered, not just the requested tier. --- ## Limits | Limit | Value | |-----------------------------------|------------------| | Max clip duration (manual) | 10 minutes | | GIF max duration | 30 seconds | | Max source video (clips & AI) | 3 hours | | Full download duration | unlimited | | AI query length | 500 characters | | Clip name length | 200 characters | | Free storage per account | 1 GB | | Max API keys per account | 10 | --- ## Output Formats & Quality **Formats:** `mp4`, `mp3`, `gif` **Quality (MP4):** - `4k` - best for download-first workflows; auto-downgrades to the highest available quality at or below the request - `1080p` - `720p` FastClip may return a lower delivered MP4 quality such as `1440p`, `1080p`, `720p`, or `480p` when the source does not support the requested tier. **Quality (GIF):** - `1080p` - `720p` `mp3` exports are audio-only and ignore `quality`. **Aliases:** `high` = `1080p`, `medium` = `720p` 4K clips are slower to process and may have limited playback compatibility on some devices. Best for download-first workflows. --- ## Authentication Most clip/account endpoints require a Bearer token: ``` Authorization: Bearer sk_live_... ``` Generate API keys from the dashboard under **Account → API Keys**. Max 10 keys per account. The full key is shown once on creation and cannot be retrieved again. Public endpoints documented here include `POST /v1/clip/info` and the share endpoints. --- ## Base URL ``` https://api.fastclip.dev/v1 ``` --- ## API Endpoints ### POST /v1/clip/info - Validate URL & get video metadata **No authentication required.** Use this to validate a URL, check video duration (for cost estimation), and confirm platform support before submitting a clip job. **Request:** ```json { "url": "https://youtube.com/watch?v=..." } ``` **Response:** ```json { "title": "Video Title", "duration": 3600.5, "thumbnail": "https://...", "preview_url": null, "preview_embed_url": "https://...", "max_height": 1080 } ``` --- ### POST /v1/clip - Manual clip with timestamps **Auth required.** Submit a clip job with explicit start and end timestamps (in seconds). Use `quality` for `mp4` and `gif` outputs. Omit it for `mp3`. For `mp4`, accepted request values are `720p`, `1080p`, and `4k`. GIF supports `720p` and `1080p` only. **Request:** ```json { "url": "https://youtube.com/watch?v=...", "start": 120, "end": 180, "format": "mp4", "quality": "4k" } ``` **Response:** ```json { "job_id": "a1b2c3d4e5f6g7h8", "status": "pending" } ``` Poll `GET /v1/clip/{job_id}` until `status` is `"complete"`. --- ### POST /v1/clip/auto - AI auto-clip with natural language **Auth required.** Describe what to clip; the AI finds matching segments and clips them. Use `quality` for `mp4` and `gif` outputs. Omit it for `mp3`. For `mp4`, accepted request values are `720p`, `1080p`, and `4k`. GIF supports `720p` and `1080p` only. **Request:** ```json { "url": "https://youtube.com/watch?v=...", "query": "the part about neural networks", "format": "mp4", "quality": "4k" } ``` **Response:** ```json { "job_id": "x1y2z3a4b5c6d7e8", "status": "pending", "reserved": 0.30 } ``` When complete, the job status response includes a `clips` array with per-segment download URLs. --- ### POST /v1/clip/analyze - AI timestamps + transcript excerpts **Auth required.** Returns matching segments with timestamps, confidence scores, and transcript excerpts - without rendering any output clip. Use this to preview results or build a filtering pipeline before committing to clip rendering. Cost: $0.10 per hour of source video (rounded up). **Request:** ```json { "url": "https://youtube.com/watch?v=...", "query": "all mentions of machine learning" } ``` **Response:** ```json { "segments": [{ "start": 45, "end": 112, "excerpt": "...where machine learning really changed the game...", "confidence": 0.92 }], "cost": 0.10 } ``` `excerpt` contains transcript text when available (may be empty on some sources). Pair with `POST /v1/clip` to clip only the segments you want. --- ### GET /v1/clip/{job_id} - Check job status & get download URL **Auth required.** Poll this endpoint until `status` is `"complete"` or `"failed"`. **Response (complete - manual clip):** ```json { "job_id": "a1b2c3d4e5f6g7h8", "status": "complete", "progress": 100, "status_message": "Done!", "download_url": "https://r2.../abc123.mp4", "file_name": "clip_2-00-3-00.mp4", "format": "mp4", "quality": "1080p", "aspect_ratio": "16:9", "saved_to_library": true, "clip_id": "a1b2c3d4e5f6g7h8", "share_url": "/c/a1b2c3d4e5f6g7h8", "embed_url": "/embed/a1b2c3d4e5f6g7h8", "cost": 0.10 } ``` For full downloads, `saved_to_library` defaults to `false`. When it stays `false`, the job still returns a `download_url`, but `clip_id`, `share_url`, and `embed_url` are omitted and the download stays out of History. **Response (complete - auto-clip with multiple segments):** ```json { "job_id": "x1y2z3a4b5", "status": "complete", "progress": 100, "clips": [ { "start": 45, "end": 112, "download_url": "https://...", "file_size": 5242880, "format": "mp4", "quality": "4k", "share_url": "/c/clip123", "embed_url": "/embed/clip123", "aspect_ratio": "16:9" }, { "start": 300, "end": 340, "download_url": "https://...", "file_size": 2097152, "format": "mp4", "quality": "1080p", "share_url": "/c/clip456", "embed_url": "/embed/clip456", "aspect_ratio": "9:16" } ], "cost": 0.30 } ``` **Status progression:** | Status | Meaning | |---------------------------|----------------------------------------------| | `pending` | Job queued | | `analyzing` | AI is analyzing the video (auto-clip only) | | `downloading` | Downloading source video | | `processing` | Trimming / encoding clip | | `processing segment N/M` | Encoding segment N of M (multi-segment) | | `uploading` | Uploading to cloud storage | | `complete` | Done - download URL ready | | `failed` | Failed - see `error` field. Full refund issued. | --- ## Video Tool Endpoints ### POST /v1/download - Download full MP4 video or MP3 audio (no cuts) Download the complete source without any trimming. Returns a job_id for polling. **Request:** ```json { "url": "https://youtube.com/watch?v=dQw4w9WgXcQ", "format": "mp4", "quality": "4k", "save_to_library": true } ``` **Fields:** | Field | Type | Required | Notes | |-------------------|---------|----------|----------------------------------------| | `url` | string | yes | YouTube URL | | `format` | string | no | `mp4` or `mp3`. Default: `mp4` | | `quality` | string | no | `4k`, `1080p`, `720p`, `high`, `medium`. Applies to `mp4` only. Omit for `mp3`. Default for `mp4`: `high` (→ `1080p`). FastClip auto-downgrades to the highest available quality at or below the request. | | `save_to_library` | boolean | no | Default: `false`. When `true`, the full download is added to History and gets a share link. | **Response:** ```json { "job_id": "a1b2c3d4e5f6g7h8", "status": "pending" } ``` Poll via `GET /v1/clip/{job_id}`. On completion, `download_url` contains a presigned R2 link (expires 24 hours). The final `format` and `quality` fields in the job response reflect the output that was actually delivered. If `save_to_library` is omitted or `false`, the full download is not shown in History and no `share_url` or `embed_url` is generated. If `true`, it behaves like other saved library items. **Cost:** Starts at $0.05 flat per download. True 4K MP4 downloads cost $0.10. **Limits:** No duration limit. Counts toward the 20 clips/hour rate limit. --- ### POST /v1/transcript - Get full video transcript Fetch the complete transcript for a YouTube video. Returns instantly (synchronous). **Request:** ```json { "url": "https://youtube.com/watch?v=dQw4w9WgXcQ" } ``` **Response:** ```json { "text": "[0:00:00] Hello everyone\n[0:00:03] Welcome to the video...", "segments": [ { "start": 0.0, "end": 3.5, "text": "Hello everyone" }, { "start": 3.5, "end": 7.2, "text": "Welcome to the video" } ], "duration": 3600.5, "cost": 0.02 } ``` **Fields in response:** | Field | Type | Notes | |------------|--------|----------------------------------------------------| | `text` | string | Full transcript with `[H:MM:SS]` timestamps | | `segments` | array | Each segment has `start` (float), `end` (float), `text` (string) | | `duration` | float | Video duration in seconds | | `cost` | float | Amount charged ($0.02) | **Cost:** $0.02 flat per transcript. **Errors:** Returns HTTP `404` if no transcript is available for the video. Balance is refunded automatically. --- ## Clip Management Endpoints ### GET /v1/clips - List clip history Paginated, most recent first. **Query params:** `?page=1&per_page=20` **Response:** ```json { "clips": [{ "id": "a1b2c3d4e5f6g7h8", "name": "Intro Section", "format": "mp4", "quality": "1080p", "duration": 60, "file_size": 1048576, "pinned": true, "expires_at": "", "hours_left": null, "download_url": "https://r2.../a1b2c3.mp4", "share_url": "/c/a1b2c3d4e5f6g7h8", "embed_url": "/embed/a1b2c3d4e5f6g7h8", "aspect_ratio": "16:9", "source_title": "My Source Video", "created": "2026-03-30T12:00:00Z" }], "page": 1, "per_page": 20, "total_items": 47, "total_pages": 3 } ``` History includes rendered clips plus full downloads where `save_to_library=true` was used on `POST /v1/download`. Saved items expose both `share_url` and `embed_url`, and the `quality` field reflects the delivered output quality after any downgrade. --- ### PATCH /v1/clips/{clip_id} - Rename a clip **Request:** ```json { "name": "Final Intro Cut" } ``` **Response:** ```json { "id": "a1b2c3d4e5f6g7h8", "name": "Final Intro Cut" } ``` --- ### POST /v1/clips/{clip_id}/pin - Pin clip to prevent expiration Pinned clips don't expire. They count against your storage quota. **Response:** ```json { "id": "a1b2c3d4e5f6g7h8", "pinned": true } ``` Returns `409` if storage quota is full. --- ### POST /v1/clips/{clip_id}/unpin - Unpin clip (starts 24hr expiry countdown) **Response:** ```json { "id": "a1b2c3d4e5f6g7h8", "pinned": false, "expires_at": "2026-03-31T12:00:00+00:00" } ``` --- ### DELETE /v1/clips/{clip_id} - Permanently delete a clip **Response:** ```json { "id": "a1b2c3d4e5f6g7h8", "deleted": true, "storage_freed": 40509 } ``` `storage_freed` is in bytes. This action cannot be undone. --- ## Account Endpoints ### GET /v1/balance - Check current balance **Response:** ```json { "balance": 4.90 } ``` --- ### GET /v1/cards - List saved payment cards Cards are added during deposits / checkout flows. Listing does not require API Reload to be enabled. **Response:** ```json { "cards": [{ "id": "pm_1abc123", "brand": "visa", "last4": "4242", "exp_month": 12, "exp_year": 2027, "name": "Jane Doe", "address": { "line1": "123 Main St", "line2": "", "city": "Cleveland", "state": "OH", "postal_code": "44114", "country": "US" }, "is_default": true }] } ``` --- ### DELETE /v1/cards/{payment_method_id} - Remove a saved payment card Use the `pm_...` id returned by `GET /v1/cards`. **Response:** ```json { "removed": true } ``` --- ### POST /v1/reload - Reload balance with a saved card Requires **API Reload** to be enabled in Settings. Optional reload password if set. **Request:** ```json { "amount": 2500, "reload_password": "..." } ``` `amount` is in cents ($25.00 = 2500). Range: $5-$500. Rate limit: 10/hour. **Response:** ```json { "success": true, "payment_intent_id": "pi_3T...", "amount": 2500, "balance": 29.90 } ``` If email confirmation is enabled, returns a `pending` status and sends an approval email before charging. When email confirmation is enabled, the immediate response shape is: ```json { "pending": true, "message": "Confirmation email sent to you@example.com. Approve to complete the reload.", "amount": 2500 } ``` The email approval link opens a confirmation page and completes the charge. --- ## Storage Endpoints ### GET /v1/storage - Check storage usage Returns storage limit, pinned/temp usage, and storage-purchase history. **Response:** ```json { "storage_limit_gb": 106.0, "pinned_bytes": 67204622, "temp_bytes": 142813977, "pinned_mb": 64.1, "temp_mb": 136.2, "total_used_mb": 200.3, "storage_limit_mb": 108544.0, "purchases": [] } ``` ### POST /v1/storage/purchase - Buy additional storage (one-time) **Request:** ```json { "gb": 5 } ``` **Storage add-on pricing (one-time, no recurring fees):** | Pack | Price | |---------|-------| | 5 GB | $9 | | 10 GB | $15 | | 25 GB | $29 | | 50 GB | $49 | | Custom | $0.99/GB (minimum 1 GB) | Storage is permanently added to the account. **Response:** ```json { "gb_added": 5, "price": 9.0, "new_storage_gb": 6.0, "new_balance": 25.9 } ``` --- ## Share Links Each saved library item gets a public share URL. No authentication needed to view. - **Share page:** `https://fastclip.dev/c/{clip_id}` - **Embed page:** `https://fastclip.dev/embed/{clip_id}` - **Share API:** `GET /v1/share/{clip_id}` **Public share response:** ```json { "id": "zmv8w8v29l5c727", "name": "Clip.mp4", "format": "mp4", "quality": "720p", "file_size": 14511843, "duration": 318, "aspect_ratio": "16:9", "share_url": "/c/zmv8w8v29l5c727", "embed_url": "/embed/zmv8w8v29l5c727", "stream_url": "https://...", "download_url": "https://...", "pinned": true, "expires_at": "", "hours_left": null } ``` Embed URL example: ```html
``` Share links and embed URLs expire when the item expires (unless pinned). Unsaved full downloads do not get share links or embed URLs. --- ## Clip Lifecycle 1. New library items expire after **24 hours** by default. 2. **Pin** a clip to keep it permanently (counts against your storage quota). 3. **Unpin** starts a fresh 24-hour countdown. Full downloads only enter this lifecycle when `save_to_library` is `true`. 4. Expired clips return `404`. Download URLs are presigned and regenerated on each request. --- ## Rate Limiting | Scope | Limit | |--------------------------------|-------------------| | API-key requests | 60 req/min per key | | Clip jobs | 20 per hour per user | | Reload operations | 10 per hour | | Unauthenticated endpoints | 60 req/min per IP | All API responses include rate limit headers: ``` X-RateLimit-Limit: 60 X-RateLimit-Remaining: 8 X-RateLimit-Reset: 1711814400 Retry-After: 42 # only on 429 responses ``` Some infrastructure routes are excluded from rate limiting, but the public endpoints covered here are rate-limited as shown above. --- ## Error Responses All errors return JSON with a `detail` field: ```json { "detail": "Insufficient balance" } ``` | Status | Meaning | |--------|-------------------------------------------| | 400 | Bad request (validation error) | | 401 | Invalid or missing API key | | 402 | Insufficient balance | | 404 | Not found (clip expired or doesn't exist) | | 409 | Storage quota full | | 422 | URL unsupported or could not be loaded | | 429 | Rate limited (check `Retry-After`) | --- ## API Reload (Programmatic Balance Top-Up) API Reload lets you top up your balance using a saved payment card via the API - useful for automated pipelines. - Off by default. Enable in **Settings -> API Reload**. - Strongly recommended: set a **reload password** and/or enable **email confirmation** before enabling. - Without either security layer, anyone with your API key can charge your saved cards up to your per-transaction limit. - Per-transaction limit: $5-$500 (configurable). **Example - Python:** ```python import requests headers = {"Authorization": "Bearer sk_live_..."} # 1. Check current balance bal = requests.get("https://api.fastclip.dev/v1/balance", headers=headers).json() print(f"Balance: ${bal['balance']:.2f}") # 2. List saved cards cards = requests.get("https://api.fastclip.dev/v1/cards", headers=headers).json() for c in cards["cards"]: print(f" {c['brand']} ****{c['last4']}") # 3. Reload $25 with saved card reload = requests.post("https://api.fastclip.dev/v1/reload", headers=headers, json={"amount": 2500} # cents ).json() print(f"New balance: ${reload['balance']:.2f}") ``` --- ## AI Auto-Clip - How It Works 1. **Describe** - Provide the video URL and a plain-English description of what to clip (e.g., "the part about machine learning" or "when the host laughs"). 2. **AI Analyzes** - The AI processes the video's content, using transcripts for YouTube or audio analysis for other platforms, to find matching moments. 3. **Get Clips** - Multiple matching segments become multiple clips. Each additional segment costs $0.10 extra. **Source video limits for AI routes:** - YouTube: up to 3 hours - Other platforms: not yet supported (returns HTTP `422`) --- ## Quick-Start Code Examples ### Python - Manual clip ```python import requests, time headers = {"Authorization": "Bearer sk_live_..."} clip = requests.post( "https://api.fastclip.dev/v1/clip", headers=headers, json={ "url": "https://youtube.com/watch?v=dQw4w9WgXcQ", "start": 30, "end": 90, "format": "mp4", "quality": "1080p" } ).json() # Poll until ready while True: r = requests.get(f"https://api.fastclip.dev/v1/clip/{clip['job_id']}", headers=headers).json() if r["status"] == "complete": print(r["download_url"]) break time.sleep(2) ``` ### JavaScript - Manual clip ```javascript const response = await fetch("https://api.fastclip.dev/v1/clip", { method: "POST", headers: { "Authorization": "Bearer sk_live_...", "Content-Type": "application/json" }, body: JSON.stringify({ url: "https://youtube.com/watch?v=dQw4w9WgXcQ", start: 30, end: 90, format: "mp4", quality: "1080p" }) }); const clip = await response.json(); // Poll until ready while (true) { const r = await fetch( `https://api.fastclip.dev/v1/clip/${clip.job_id}`, { headers: { "Authorization": "Bearer sk_live_..." } } ).then(r => r.json()); if (r.status === "complete") { console.log(r.download_url); break; } await new Promise(r => setTimeout(r, 2000)); } ``` ### cURL - Manual clip ```bash curl -X POST https://api.fastclip.dev/v1/clip \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "url": "https://youtube.com/watch?v=dQw4w9WgXcQ", "start": 30, "end": 90, "format": "mp4", "quality": "1080p" }' ``` --- ## Account & Dashboard Features - **Sign up** with email/password or Google OAuth. - **Email verification** required to activate account and receive the $5.00 welcome credit. - **Balance** shown in navbar in real time. - **Clip History** - view, download, rename, pin/unpin, share, and delete past clips plus any full downloads you explicitly saved. - **API Keys** - create up to 10 named keys; revoke anytime. - **Deposits** - add funds via credit/debit card (minimum $5). Cards can be saved for future deposits and API Reload. - **Storage management** - view usage (pinned vs. temporary), buy more storage. - **Settings** - change password, configure API Reload, set per-transaction limit, enable email confirmation for reloads. - **Support** - in-app contact form; responses within 24 hours. - **Email preferences** - manage notification categories (receipts, low balance warnings, API key activity, reload confirmations, clip updates, marketing). - **Delete account** - irreversible; remaining balance is forfeited. --- ## FAQ **What video sites are supported?** YouTube. More platforms (TikTok, X, Vimeo) coming soon. **How does pay-as-you-go work?** Deposit funds (minimum $5). Manual clips cost $0.10 each. AI auto-clip costs $0.20 per hour of source video (rounded up). Full downloads start at $0.05. True 4K MP4 jobs cost more, but only when FastClip actually delivers 4K. No monthly fees, no subscriptions. **What is AI Auto-Clip?** Describe what you want to clip in plain English and our AI analyzes the video to find matching segments. It can return multiple clips if several moments match. **What's the maximum clip length?** 10 minutes for both manual and AI clips. **How long are download links valid?** 24 hours unless pinned. Pinned library items stay permanently until unpinned or deleted. Full downloads only get History and share-link behavior when `save_to_library` is enabled. **What if a clip fails?** You're never charged for failed clips. Any reserved amount is automatically refunded. **Is API Reload secure?** Off by default. Set a reload password and/or enable email confirmation when enabling it. Without either, anyone with your API key can charge your saved cards up to your per-transaction limit (max $500). **What are the rate limits?** 60 req/min per API key; 20 clip jobs/hour per user; 10 reloads/hour. **Do I need a credit card to start?** No. Every new account gets $5.00 free after email verification - enough for 50 manual clips. **What is AI Analyze?** Returns matching timestamps, confidence scores, and transcript excerpts without rendering a clip. Costs $0.10/hr of source video. Useful for previewing before clipping or building custom pipelines. **Are deposits refundable?** No. All deposits are non-refundable. Balance stays in your account until used. Remaining balance is forfeited on account deletion. **What output formats are available?** MP4 (video), MP3 (audio only), GIF. MP4 requests support 720p, 1080p, and 4K. GIF stays on 720p and 1080p. MP3 ignores video quality. **What should I know about 4K exports?** 4K clips are slower to process and may have limited playback compatibility on some devices. Best for download-first workflows. On our benchmark, a 4K full download was about 3.6x slower and about 5.6x larger than the 1080p-compatible path, and the 4K clip output was about 7x larger than the 1080p clip. **What happens if the source doesn't support my requested quality?** FastClip auto-downgrades to the highest available quality at or below your request. If you request 4K and the source only supports 1080p, FastClip exports 1080p. If you request 720p and the source tops out at 480p, FastClip exports 480p. The delivered quality is returned in the API response, shown in History, and used for pricing so you are not charged a 4K premium unless true 4K is delivered. **Can I manage clips through the API?** Yes. List history (`GET /v1/clips`), rename (`PATCH /v1/clips/{id}`), pin/unpin (`POST /v1/clips/{id}/pin` and `/unpin`), delete (`DELETE /v1/clips/{id}`). Full downloads only appear there when `POST /v1/download` is called with `save_to_library=true`. **How does clip storage work?** 1 GB free per account (pinned clips only). Storage add-ons: 5 GB ($9), 10 GB ($15), 25 GB ($29), 50 GB ($49), custom at $0.99/GB. One-time purchase, no recurring fees. --- ## Contact Email: admin@fastclip.dev Support form: https://fastclip.dev (Account -> Support) --- ## Legal - Privacy Policy: https://fastclip.dev/privacy - Terms of Service: https://fastclip.dev/terms - Refund Policy: https://fastclip.dev/refund By using FastClip, you confirm you will only clip content you have the right to use. Compliance with third-party platform terms of service is your responsibility. --- *Last updated: 2026-04-04*