# FastClip API Documentation FastClip is an API for trimming, clipping, and analyzing video and audio files. Upload your media, then create clips, run AI analysis, or extract transcripts — all through a simple REST API. Key capabilities: - **Trim and clip** — extract segments from uploaded video or audio with precise start/end times - **AI auto-clip** — describe what you want and let AI find and render the best moments - **AI analyze** — get timestamped segment suggestions without rendering - **Transcription** — full speech-to-text with word-level timestamps - **Captions** — reusable caption presets and burned-in captions for uploaded MP4 video clips - **Webhooks** — get notified when uploads, clips, and billing events occur - **Clip library** — share, embed, pin, and manage your output clips --- ## Base URL ```text https://api.fastclip.dev ``` --- ## Authentication FastClip supports two auth modes: 1. API key in `Authorization: Bearer sk_live_...` 2. Site session cookies for dashboard/browser flows Most endpoints accept either mode through the shared auth middleware. Session-only endpoints include: - `POST /v1/account/signup-credit` - `DELETE /v1/account` - API key management (`POST/GET/DELETE /v1/keys...`) - Saved card management (`GET/DELETE /v1/cards...`) - Caption preset/font management (`GET/POST/PATCH/DELETE /v1/caption-presets...`, `GET/POST/DELETE /v1/caption-fonts...`) Public no-auth endpoints: - `GET /v1/share/{clip_id}` - `POST /v1/share/{clip_id}/view` - `GET /v1/reload/approve` (tokenized approval link) - `POST /v1/reload/approve` (tokenized approval submit) --- ## Upload-First Flow FastClip has two public upload paths: - **Simple single upload:** `POST /v1/upload/request`. Use this for small files and simple integrations. The whole file is uploaded with one HTTP `PUT`. - **Multipart upload:** `POST /v1/upload/multipart/initiate` plus `POST /v1/upload/multipart/complete`. Use this for large files, parallel chunk uploads, browser uploads, and any file where retrying one failed chunk is better than retrying the whole file. Recommended default: - Use `POST /v1/upload/request` for files at or below `96 MB`. - Use multipart for files over `96 MB`. - For large desktop/server uploads, a `32 MiB` `part_size` is a good default. - For mobile uploads, a `16 MiB` `part_size` is a good default. - Multipart parts must be at least `5 MiB` except the final part. - Max upload size is `5 GB`; max source duration is `3 hours`. Both paths produce the same `file_id`. After upload completion, poll `GET /v1/upload/{file_id}` until `status` is `ready`, then submit that `file_id` to clip, AI auto-clip, analyze, transcript, or captions endpoints. ### Simple upload flow 1. Request a single presigned upload URL. 2. Upload the entire file with one HTTP `PUT`. 3. Poll upload status until `ready`. 4. Submit clip/analyze/auto/transcript/caption jobs using `file_id`. #### 1) Request single upload URL `POST /v1/upload/request` ```json { "filename": "source.mp4", "content_type": "video/mp4", "file_size": 734003200 } ``` Response: ```json { "file_id": "upl_a1b2c3d4e5f6", "upload_url": "https://...", "expires_in": 3600, "clip_requested": false } ``` Optional one-shot clip request at upload time: ```json { "filename": "source.mp4", "content_type": "video/mp4", "file_size": 734003200, "clip": { "start": 12, "end": 48, "source_title": "My Source" } } ``` If `clip` is included, FastClip reserves clip cost, validates uploaded media, and auto-queues a clip job after validation. #### 2) Upload bytes to `upload_url` Use HTTP PUT to the returned presigned URL. No FastClip auth header is required for this PUT. #### 3) Poll upload status `GET /v1/upload/{file_id}` ```json { "file_id": "upl_a1b2c3d4e5f6", "status": "ready", "filename": "source.mp4", "content_type": "video/mp4", "file_size": 734003200, "duration": 1200.5, "duration_seconds": 1200.5, "max_height": 1080, "format_detected": "mov,mp4,m4a,3gp,3g2,mj2", "media_kind": "video", "has_video": true, "has_audio": true, "error": null, "created_at": "2026-04-19T10:00:00Z", "expires_at": "2026-04-20T10:00:00Z", "clip_requested": false, "clip_job_id": null } ``` Upload statuses: `pending`, `processing`, `ready`, `failed` ### Multipart upload flow Use multipart when you want faster large-file uploads, parallel chunk uploads, resumable client behavior, or safer retries. 1. Choose `part_size`. 2. Compute `part_count = ceil(file_size / part_size)`. 3. Call `POST /v1/upload/multipart/initiate`. 4. Upload each byte range to its matching part `url` with HTTP `PUT`. 5. Capture each part's `ETag` response header. 6. Call `POST /v1/upload/multipart/complete` with all uploaded part numbers and ETags. 7. Poll `GET /v1/upload/{file_id}` until `ready`. #### 1) Initiate multipart upload `POST /v1/upload/multipart/initiate` ```json { "filename": "source.mp4", "content_type": "video/mp4", "file_size": 2147483648, "part_size": 33554432, "part_count": 64 } ``` Response: ```json { "file_id": "upl_a1b2c3d4e5f6", "upload_id": "multipart_upload_id", "parts": [ { "part_number": 1, "url": "https://..." }, { "part_number": 2, "url": "https://..." } ], "expires_in": 3600, "clip_requested": false } ``` The returned part URLs are already authorized. Do not send your FastClip API key to those part URLs. Each part upload is an HTTP `PUT` to the matching part URL. Optional one-shot clip requests work on multipart initiate too: ```json { "filename": "source.mp4", "content_type": "video/mp4", "file_size": 2147483648, "part_size": 33554432, "part_count": 64, "clip": { "start": 12, "end": 48, "source_title": "My Source" } } ``` #### 2) Complete multipart upload `POST /v1/upload/multipart/complete` ```json { "file_id": "upl_a1b2c3d4e5f6", "upload_id": "multipart_upload_id", "parts": [ { "part_number": 1, "etag": "etag-from-part-1" }, { "part_number": 2, "etag": "etag-from-part-2" } ] } ``` Response: ```json { "ok": true, "file_id": "upl_a1b2c3d4e5f6", "queued_validation": true } ``` After completion, poll `GET /v1/upload/{file_id}` until `status` is `ready`. #### Multipart helper endpoints - `POST /v1/upload/multipart/refresh` refreshes expired or missing part URLs. - `POST /v1/upload/multipart/abort` cancels an unfinished multipart upload. - `POST /v1/upload/abort` cancels a simple upload record before it is ready. Refresh request: ```json { "file_id": "upl_a1b2c3d4e5f6", "upload_id": "multipart_upload_id", "part_numbers": [8, 9, 10] } ``` Abort request: ```json { "file_id": "upl_a1b2c3d4e5f6", "upload_id": "multipart_upload_id" } ``` --- ## Browser Caption Workflows FastClip has two browser caption surfaces with different jobs: - **Caption Studio** is for creating, duplicating, editing, saving, and previewing reusable caption presets. Open it from the account dropdown with **Captions**. It previews styles with a test caption clip and shows the `preset_ref` you can reuse. - **Clip Studio** is where browser users apply captions to their own media. Upload a video, choose **Trim** or **AI Auto**, set output format to `MP4`, enable **Add captions**, choose a pre-made or custom preset, then run the clip job. Caption Studio does not caption an uploaded file or a history clip directly. It is the preset editor and preview surface. To use a preset in the browser, go back to Clip Studio and enable captions on an uploaded video trim or AI Auto job. Browser caption rules: - Captions are available for uploaded videos only. - Audio-only uploads use Transcript instead. - GIF and audio exports cannot receive captions; choose MP4. - Pre-made presets and saved custom presets appear in the Clip Studio caption preset dropdown. - Custom presets are account-scoped. Other users cannot see or use them. - Captioned outputs are new MP4 files; the uploaded source video is not modified. - Custom TTF/OTF fonts can be uploaded from Caption Studio. Uploaded fonts are account-scoped and can be used by custom presets. Typical browser flow: 1. Sign in. 2. Open **Account → Captions**. 3. Choose a pre-made style, duplicate it if needed, adjust font/color/stroke/position, and save the custom preset. 4. Upload a video in Clip Studio. 5. In **Trim** or **AI Auto**, set format to `MP4`. 6. Enable **Add captions**. 7. Choose the pre-made or custom preset. 8. Run the trim or AI Auto job. API caption terminology: - `preset_ref` identifies the caption style. Use `builtin:` for pre-made styles or `preset:` for account-owned custom presets. - FastClip ships a fixed 16-style pre-made caption catalog. Users can duplicate a pre-made style into an account-scoped custom preset and then diverge it. - `highlight_mode` means active spoken word highlighting. For active highlight, `words_per_caption` is clamped to 2-4. - `highlight_color` is the stored caption accent color. It is the active word color for karaoke/active highlight, the box color for highlight-box/news-ticker, and the accent color for glow-style effects. - Background highlight boxes are style effects, not the same control as active spoken word highlighting. --- ## Core Clip Endpoints ### `POST /v1/clip` - Manual trim Use uploaded `file_id` plus either a single time range or multiple segments. Single segment request: ```json { "file_id": "upl_a1b2c3d4e5f6", "start": 15, "end": 55, "format": "mp4", "quality": "1080p" } ``` Single segment trim-plus-caption request: ```json { "file_id": "upl_a1b2c3d4e5f6", "start": 15, "end": 55, "format": "mp4", "quality": "1080p", "captions": { "preset_ref": "builtin:short-form-karaoke" } } ``` Trim-plus-caption rules: - `captions` is optional. - Captions require `format: "mp4"` and a video source. - Trim cost and caption cost are additive. - Caption pricing is `$0.02` per input video minute up to 1080p, or `$0.04` per input video minute for true 4K. - Input resolution is detected automatically. Omit `quality` to preserve source resolution when 4K output is available to the account; send `quality` only when you want a lower-resolution MP4 back. - `quality: "4k"` requires a successful paid deposit. Promo codes, signup credits, free credits, and test grants do not unlock 4K output. - The captioned trim output is a new MP4 clip. Multi-segment request: ```json { "file_id": "upl_a1b2c3d4e5f6", "segments": [ { "start": 10, "end": 20 }, { "start": 45, "end": 60 } ], "format": "mp4", "quality": "4k" } ``` Responses: ```json { "job_id": "job_123", "status": "pending" } ``` ```json { "job_ids": ["job_123", "job_456"], "status": "pending" } ``` Partial queueing can return: ```json { "job_ids": ["job_123"], "status": "partial", "error": "Clip queue is temporarily unavailable" } ``` ### `GET /v1/clip/{job_id}` - Job status ```json { "job_id": "job_123", "status": "complete", "progress": 100, "status_message": "Done!", "download_url": "https://...", "file_name": "source_0-15-0-55.mp4", "format": "mp4", "quality": "1080p", "aspect_ratio": "16:9", "saved_to_library": true, "clip_id": "d9d54c23-7af8-41f8-8f6e-9ce0092f8f2f", "share_url": "/c/d9d54c23-7af8-41f8-8f6e-9ce0092f8f2f", "embed_url": "/embed/d9d54c23-7af8-41f8-8f6e-9ce0092f8f2f", "cost": 0.02, "balance": 0.98 } ``` Job status values: - `pending` - `downloading` (fetching source from storage) - `processing` - `uploading` (uploading result to storage) - `complete` - `failed` Jobs may also report transient messages like `analyzing` or `processing segment N/M` via `status_message`. ### `POST /v1/clip/auto` - AI auto-clip ```json { "file_id": "upl_a1b2c3d4e5f6", "query": "find the strongest product launch soundbites", "format": "mp4", "quality": "1080p", "captions": { "preset_ref": "builtin:short-form-karaoke" } } ``` Response: ```json { "job_id": "job_auto_123", "status": "pending", "reserved": 0.20 } ``` `captions` is optional and only works with MP4 video output. Caption pricing is additive to AI Auto-Clip pricing: `$0.02` per input video minute up to 1080p, or `$0.04` per input video minute for true 4K. Input resolution is detected automatically, 4K output requires a successful paid deposit, and unused reserved caption amount is refunded after settlement. `GET /v1/clip/{job_id}` returns auto results in `clips`. ### `POST /v1/clip/analyze` - AI analyze (no render) ```json { "file_id": "upl_a1b2c3d4e5f6", "query": "highlight moments where churn risk is discussed" // optional — defaults to general highlights } ``` Response: ```json { "segments": [ { "start": 42, "end": 71, "excerpt": "...we saw churn rise after onboarding changes...", "confidence": 0.93 } ], "cost": 0.08, "balance": 1.12 } ``` ### `POST /v1/transcript` - Transcript for uploaded media ```json { "file_id": "upl_a1b2c3d4e5f6" } ``` Response: ```json { "text": "[0:00:00] Welcome everyone...", "segments": [ { "start": 0.0, "end": 2.7, "text": "Welcome everyone" } ], "duration": 1200.5, "cost": 0.05, "balance": 0.95 } ``` Transcript pricing is tiered by source duration: `$0.02` (<=10 min), `$0.05` (<=30 min), `$0.10` (<=60 min), `$0.20` (<=120 min), `$0.40` (<=240 min). --- ## Caption Endpoints ### `POST /v1/captions` - Caption an existing video source Use this when you already have an uploaded video or an owned MP4 clip and want to add captions without trimming again. Request with upload `file_id`: ```json { "file_id": "upl_a1b2c3d4e5f6", "preset_ref": "builtin:short-form-karaoke" } ``` Request with existing clip `clip_id`: ```json { "clip_id": "d9d54c23-7af8-41f8-8f6e-9ce0092f8f2f", "preset_ref": "preset:cap_preset_123", "quality": "720p" } ``` Response: ```json { "job_id": "job_cap_123", "status": "pending", "reserved": 0.04 } ``` Rules: - Provide exactly one of `file_id` or `clip_id`. - Source must be video and output must be MP4. - Audio-only sources, GIF outputs, non-video uploads, expired clips, and already-captioned clips are rejected. - `clip_id` must reference an owned, still-available MP4 clip. - Captioned clips cannot be captioned again. - Captions create a new MP4 output and do not modify the source. - Caption pricing is based on the input video duration and detected resolution. - Captions cost `$0.02` per input video minute up to 1080p, or `$0.04` per input video minute for true 4K. - Input resolution is detected automatically. Omit `quality` to preserve the source resolution when 4K output is available to the account; send `quality` only when you want a lower-resolution MP4 back. - 4K output requires a successful paid deposit. Free, promo, signup, and test credits can export up to 1080p. Caption billing examples: - 61-second standard caption job: `2 * $0.02 = $0.04`. - 10-minute standard caption job: `10 * $0.02 = $0.20`. - 10-minute true 4K caption job: `10 * $0.04 = $0.40`. - A `$0.02` trim plus 61 seconds of standard captions costs `$0.06` total for that trim-plus-caption job. ### `GET /v1/captions/{job_id}` - Caption job status ```json { "job_id": "job_cap_123", "status": "complete", "progress": 100, "captioned": true, "clip_id": "cap_clip_123", "download_url": "https://...", "share_url": "/c/cap_clip_123", "embed_url": "/embed/cap_clip_123", "cost": 0.04, "balance": 0.96 } ``` ### `GET /v1/caption-presets` - List presets Session-only in v1. Use Caption Studio to copy `preset_ref` for API reuse. Query: - `scope=all` - `scope=built_in` - `scope=custom` Response: ```json [ { "preset_ref": "builtin:short-form-karaoke", "scope": "built_in", "slug": "short-form-karaoke", "name": "Short-Form Karaoke", "editable": false, "font_name": "Bangers", "font_size": 77, "words_per_caption": 3, "highlight_mode": true, "highlight_color": "#fcea2a", "position_x": 0.5, "position_y": 0.92 } ] ``` ### `POST /v1/caption-presets` - Save a custom preset Session-only browser product flow in v1. Custom presets are authored in Caption Studio, not by public API-key integrations. Custom presets start from `clone_from_preset_ref` and can override style fields. ```json { "name": "My Hook Captions", "clone_from_preset_ref": "builtin:short-form-karaoke", "font_name": "Bangers", "font_size": 77, "words_per_caption": 3, "text_color": "#ffffff", "stroke_enabled": true, "stroke_width": 4, "stroke_color": "#000000", "highlight_mode": true, "highlight_color": "#fcea2a", "position_x": 0.5, "position_y": 0.92 } ``` ### `POST /v1/caption-fonts` - Upload a custom font Session-only in v1. ```text POST /v1/caption-fonts?filename=MyFont.ttf Content-Type: multipart/form-data file=@MyFont.ttf ``` Rules: - TTF and OTF files are accepted. - Max font upload size is `10 MB`. - Uploaded fonts are account-scoped. - Use the returned `font_id` when saving a custom preset with `font_source: "upload"`. --- ## Format and Quality Rules Clip export formats: - `mp4` - `mp3` - `wav` - `m4a` - `flac` - `gif` (site session only) Alias: - `aac` is accepted as alias input for `m4a` Quality request values for video clips: - `4k` - `1080p` - `720p` - `high` (alias of `1080p`) - `medium` (alias of `720p`) Rules: - Audio exports do not accept `quality`. - GIF does not support `4k`. - GIF exports are website-only and not available via API key. - Auto-clip does not allow GIF output. - Audio uploads can only export `mp3`, `wav`, `m4a`, `flac`. - API-key requests on video uploads export `mp4`; signed-in browser Clip Studio can also export `gif`. - `4k` output requires a successful paid deposit. Promo codes, signup credits, free credits, and test grants can export up to 1080p. - Delivered video quality can be lower than requested when source resolution is lower. --- ## Pricing All values in USD. | Operation | Price | | --- | --- | | Manual trim | `$0.02` per segment | | Manual trim true 4k surcharge | `+$0.02` per segment | | Captions up to 1080p MP4 | `$0.02` per input video minute | | Captions true 4K MP4 | `$0.04` per input video minute | | Transcript (<=10 min) | `$0.02` | | Transcript (<=30 min) | `$0.05` | | Transcript (<=60 min) | `$0.10` | | Transcript (<=120 min) | `$0.20` | | Transcript (<=240 min) | `$0.40` | | Upload one-shot clip reservation | `$0.02` | | AI Analyze (<=30 min) | `$0.08` | | AI Analyze (<=60 min) | `$0.15` | | AI Analyze (<=120 min) | `$0.25` | | AI Analyze (<=240 min) | `$0.40` | | AI Auto-Clip (<=30 min) | `$0.10` | | AI Auto-Clip (<=60 min) | `$0.20` | | AI Auto-Clip (<=120 min) | `$0.35` | | AI Auto-Clip (<=240 min) | `$0.50` | Notes: - Multi-segment manual trims are charged per segment. - Trim-plus-caption jobs charge trim and caption costs together. - Caption input resolution is detected automatically; `quality` is optional and only needed to cap the returned MP4 lower than the input. If the account has no paid deposit, output is capped at 1080p. - Clip jobs reserve balance first and settle on completion. - Failed queued work is refunded. Deposits and bonuses: - Minimum deposit: `$5.00` - First paid top-up bonus: `+50%` - Any paid top-up of `$50.00` or more: `+10%` - Bonuses stack when both conditions apply. Welcome defaults: - Signup credit endpoint grants `$1.00`. - Default storage allocation is `10 GB`. --- ## Limits | Limit | Value | | --- | --- | | Max upload size | `5 GB` | | Max upload duration | `3 hours` | | Max clip duration per segment | `10 minutes` | | Max GIF segment duration | `30 seconds` | | Max manual segments per request | `50` | | Max caption font upload size | `10 MB` | | Max AI query length | `500 chars` | | Max API key name length | `100 chars` | | Max clip rename length | `200 chars` | | Max clip bulk delete size | `50 ids` | | Max API keys per account | `10` | | Max webhooks per account | `10` | Rate limits return HTTP `429` on overflow. --- ## Supported Upload Media Types The upload validator accepts common video and audio containers. Extensions: - Video: `mp4`, `mov`, `avi`, `mkv`, `webm`, `m4v`, `flv` - Audio: `mp3`, `wav`, `aac`, `flac`, `ogg`, `m4a`, `wma` Validation occurs after upload using file signature checks plus `ffprobe` metadata. --- ## Clip Library and Share History and clip management: - `GET /v1/clips` - `PATCH /v1/clips/{clip_id}` - `POST /v1/clips/{clip_id}/pin` - `POST /v1/clips/{clip_id}/unpin` - `POST /v1/clips/bulk-delete` - `DELETE /v1/clips/{clip_id}` Public share and owner controls: - `GET /v1/share/{clip_id}` - `POST /v1/share/{clip_id}/view` - `GET /v1/share/{clip_id}/viewer-state` - `PATCH /v1/share/{clip_id}/view-count-visibility` Semantics: - Completed clip outputs include `clip_id`, `share_url`, and `embed_url`. - Unpinned clips expire after about 24 hours. - Pinned clips do not auto-expire. - Expired clips return 404 on share endpoints. - Share views are deduplicated (visitor id or IP/user-agent hash). --- ## Webhooks Webhook CRUD: - `POST /v1/webhooks` - `GET /v1/webhooks` - `GET /v1/webhooks/{webhook_id}` - `PATCH /v1/webhooks/{webhook_id}` - `DELETE /v1/webhooks/{webhook_id}` - `POST /v1/webhooks/{webhook_id}/test` - `GET /v1/webhooks/{webhook_id}/deliveries` Valid event names: - `clip.complete` - `clip.failed` - `clip.auto.segment_complete` - `clip.auto.segment_failed` - `clip.expired` - `upload.ready` - `upload.failed` - `balance.low` - `balance.empty` - `balance.reloaded` - `btc.deposit.failed` - `card.reload.failed` Delivery envelope: ```json { "event": "upload.ready", "data": { "file_id": "upl_a1b2c3d4e5f6", "filename": "source.mp4" } } ``` Delivery headers: - `X-FastClip-Signature: sha256=` - `X-FastClip-Event: ` - `X-FastClip-Delivery-ID: ` Signature input is canonical JSON (sorted keys, compact separators) HMAC-SHA256 signed with your webhook secret. ### Example payload: `upload.ready` ```json { "event": "upload.ready", "data": { "file_id": "upl_a1b2c3d4e5f6", "filename": "podcast.wav", "file_size": 52428800, "duration": 1810.2, "duration_seconds": 1810.2, "max_height": 0, "format_detected": "wav", "content_type": "audio/wav", "media_kind": "audio", "has_video": false, "has_audio": true, "clip_requested": false, "clip_job_id": "" } } ``` ### Example payload: `clip.complete` ```json { "event": "clip.complete", "data": { "job_id": "job_123", "clip_id": "d9d54c23-7af8-41f8-8f6e-9ce0092f8f2f", "format": "mp3", "quality": "", "duration": 32.4, "download_url": "https://...", "cost": 0.02 } } ``` --- ## Billing, Storage, and Account Balance and deposits: - `GET /v1/balance` - `POST /v1/deposit` - `POST /v1/deposit/finalize` - `POST /v1/deposit/btcpay` - `GET /v1/deposit/btcpay/status/{attempt_id}` API reload and account settings: - `GET /v1/account/reload-settings` - `POST /v1/account/reload-settings` - `POST /v1/reload` - `GET /v1/reload/approve` - `POST /v1/reload/approve` `POST /v1/reload` request notes: - `amount` is required in cents (`500` to `50000` => `$5` to `$500`). - `reload_password` is required only if you configured a reload password in settings. - For direct reloads (email confirmation turned off), provide an idempotency key via either: - request body field `attempt_key`, or - `Idempotency-Key` header (or `X-Idempotency-Key`). - If both body and header idempotency keys are provided, they must match. `POST /v1/reload` response modes: - Email confirmation enabled: returns `200` with `{ "pending": true, "message": "...", "amount": ... }` and sends approval email. - Email confirmation disabled: attempts immediate saved-card charge and returns success payload on completion. Common reload errors: - `400` invalid request (for example missing/invalid/conflicting idempotency key on direct reload). - `403` reload disabled or reload password missing/invalid. - `400` no saved card available for the account. Storage: - `GET /v1/storage` - `POST /v1/storage/purchase` Storage purchase pricing: - `5 GB` -> `$9` - `10 GB` -> `$15` - `25 GB` -> `$29` - `50 GB` -> `$49` - Custom -> `$0.99/GB` Cards: - `GET /v1/cards` - `DELETE /v1/cards/{payment_method_id}` Cards auth note: - Cards endpoints require a signed-in site session. - API keys are not accepted for cards endpoints. --- ## API Keys - `POST /v1/keys` - `GET /v1/keys` - `DELETE /v1/keys/{key_id}` API key create response returns the full key exactly once. --- ## Usage - `GET /v1/usage` — usage summary - `GET /v1/usage/export.csv` — CSV export Usage auth note: - Usage endpoints require a signed-in site session. - API keys are not accepted for usage endpoints. --- ## Support - `POST /v1/support` - `POST /v1/feature-request` --- ## Common Errors | HTTP | Meaning | | --- | --- | | `400` | Invalid request fields or format/quality mismatch | | `401` | Missing/invalid API key or session | | `402` | Insufficient balance | | `403` | Authenticated but not allowed for this action, including gated 4K output | | `404` | Resource not found or no longer available | | `409` | State conflict (for example upload not ready) | | `410` | Uploaded source expired | | `422` | Validation failed (for example duration or unsupported media) | | `429` | Rate limited | | `500` | Internal server error | | `503` | Temporary upstream or queue unavailability | --- ## Minimal cURL Example This example uses the simple single-upload endpoint. For large files, use the multipart flow above instead of `POST /v1/upload/request`. ```bash # 1) Request single upload URL curl -sS -X POST "https://api.fastclip.dev/v1/upload/request" \ -H "Authorization: Bearer sk_live_xxx" \ -H "Content-Type: application/json" \ -d '{"filename":"source.mp4","content_type":"video/mp4","file_size":734003200}' # 2) PUT bytes to upload_url (from response) curl -X PUT "https://...presigned..." \ -H "Content-Type: video/mp4" \ --data-binary @source.mp4 # 3) Poll upload curl -sS "https://api.fastclip.dev/v1/upload/upl_a1b2c3d4e5f6" \ -H "Authorization: Bearer sk_live_xxx" # 4) Create clip curl -sS -X POST "https://api.fastclip.dev/v1/clip" \ -H "Authorization: Bearer sk_live_xxx" \ -H "Content-Type: application/json" \ -d '{"file_id":"upl_a1b2c3d4e5f6","start":12,"end":42,"format":"mp4","quality":"1080p"}' # 5) Poll job curl -sS "https://api.fastclip.dev/v1/clip/job_123" \ -H "Authorization: Bearer sk_live_xxx" ``` ## Multipart cURL Outline Use this endpoint family for large files. The important customer-facing pieces are `file_id`, `upload_id`, part `url`s, and the ETags returned by each part `PUT`. ```bash # 1) Initiate multipart upload curl -sS -X POST "https://api.fastclip.dev/v1/upload/multipart/initiate" \ -H "Authorization: Bearer sk_live_xxx" \ -H "Content-Type: application/json" \ -d '{"filename":"source.mp4","content_type":"video/mp4","file_size":2147483648,"part_size":33554432,"part_count":64}' # 2) PUT each byte range to its matching parts[N].url. # Capture the ETag response header for every successful part PUT. # 3) Complete multipart upload curl -sS -X POST "https://api.fastclip.dev/v1/upload/multipart/complete" \ -H "Authorization: Bearer sk_live_xxx" \ -H "Content-Type: application/json" \ -d '{"file_id":"upl_a1b2c3d4e5f6","upload_id":"multipart_upload_id","parts":[{"part_number":1,"etag":"etag-from-part-1"},{"part_number":2,"etag":"etag-from-part-2"}]}' # 4) Poll upload validation curl -sS "https://api.fastclip.dev/v1/upload/upl_a1b2c3d4e5f6" \ -H "Authorization: Bearer sk_live_xxx" ``` --- ## Contact and Legal - Support: admin@fastclip.dev - Website: https://fastclip.dev - Terms: https://fastclip.dev/terms - Privacy: https://fastclip.dev/privacy - Refund policy: https://fastclip.dev/refund Use FastClip only with content you have rights to process and distribute. --- Last updated: 2026-04-29