# each::labs | Video API | Multi-capability video editing EACHLABS Video API - the easiest way for an AI agent or developer to edit video. 44 curated operations: editing (trim, segment, concat, crossfade, speed, reframe), encoding (transcode, scale, gif), audio (extract_audio, loudnorm, audio_replace, audio_master), captions (captions, subtitle_compose), analysis (probe, scene_detect, silence_detect), streaming (hls_ladder, package_abr) - plus a raw ffmpeg escape hatch (mode=run_ffmpeg with an argv array, argv[0]=ffmpeg). Inputs are media URLs (input_url / input_urls); outputs land on the EACHLABS CDN. Billed $0.0015 per compute-second; every job includes 200 MB of output delivery free, then $0.30/GB. mode=capability with capability+params is the recommended path. ## API Information - **Model Slug:** eachlabs-video-api - **Branded URL:** https://www.eachlabs.ai/eachlabs/each-tools/eachlabs-video-api - **Provider:** eachlabs - **Category:** AI Models - **Output Type:** video - **Status:** active - **Base Cost:** Calculated using formula: 0 * 0.0015 - **Estimated Processing Time:** 5 seconds - **Interactive Demo:** https://www.eachlabs.ai/ai-models/eachlabs-video-api ## Pricing - **Charge Type:** dynamic - **Pricing Details:** Calculated using formula: 0 * 0.0015 ### Pricing Rules | Condition | Pricing | | --- | --- | | output.output_gb exists "undefined" AND output.output_gb > "0.2" | billed_seconds * 0.0015 + (output_gb - 0.2) * 0.3 | | Rule 2 | billed_seconds * 0.0015 | | Default (fallback) | billed_seconds * 0.0015 | ## Input Schema | Parameter | Type | Required | Default | Constraints | Description | |-----------|------|----------|---------|-------------|-------------| | mode | string | No | capability | capability, run_ffmpeg | capability: run one of 45 curated operations chosen via capability + params (default, recommended). run_ffmpeg: submit a raw ffmpeg/ffprobe argv array for anything the curated set does not cover (per-organization beta grant; argv[0] must be ffmpeg or ffprobe). | | capability | string | No | transcode | transcode, trim, segment, thumbnails, scale, extract_audio, gif, watermark, concat, concat_copy, crossfade, rotate, crop, pad, reframe, reframe_track, speed, volume, loudnorm, reverse, fade, color, lut3d, stills, poster, captions, subtitle_compose, title_card, overlay, sticker_overlay, audio_replace, audio_duck, audio_master, audio_analysis, probe, scene_detect, silence_detect, silence_remove, keep_ranges, silence_split, slideshow, storyboard_sprites, hls_ladder, package_abr, package_abr_ladder | The operation to run when mode=capability (each documents its own params schema). Edit: trim (lossless keyframe cut), silence_remove / keep_ranges (alias) (keep only given time ranges, frame-accurate re-encode), segment (fixed-length chunks), silence_split (split on silences with caps), speed (0.25x-4x), reverse, concat (join 2-10 clips, re-encode), concat_copy (lossless join of 2-50 same-codec chunks), crossfade (join with transition), slideshow (2-50 images to video). Geometry: scale (resize), crop, pad, rotate (90/180/270), reframe (social 9:16/1:1/4:5/16:9), reframe_track (pan a crop window via a crop-track sidecar). Encode: transcode (h264/vp9/hevc/av1 re-encode), gif (animated GIF). Audio: extract_audio (mp3/wav/m4a, optional STT-ready resample+mono), volume (0-10x gain), loudnorm (EBU R128 normalize), audio_replace (replace/mix a video's audio), audio_duck (duck music under speech), audio_master (compress + normalize + limit). Look: color (brightness/contrast/saturation/gamma), lut3d (.cube 3D-LUT), fade (fade in/out), watermark (image overlay), overlay (video overlay), sticker_overlay (timed sticker), title_card (rendered title clip). Captions: captions (burn SRT/VTT/ASS), subtitle_compose (server-authored animated word-timed captions). Images: stills (single frame jpg/png), thumbnails (frames at an interval), poster (mp4 + jpg poster), storyboard_sprites (sprite sheet + WebVTT index). Analysis (JSON result, no media): probe (ffprobe), scene_detect (hard cuts), silence_detect (silent spans), audio_analysis (loudness/peaks). Streaming: hls_ladder (multi-rendition HLS), package_abr (single-rendition HLS+DASH stream-copy), package_abr_ladder (multi-rendition HLS+DASH ladder). | | input_url | string | No | - | - | Source video/audio to process. Accepts a publicly downloadable https URL with a media file extension (staged automatically) or an s3:// URI the engine can read. | | input_urls | array | No | - | - | Ordered inputs for multi-input capabilities (e.g. watermark: [video, overlay]) or a run_ffmpeg argv referencing {input0}/{input1}. Each entry accepts a publicly downloadable https media URL (staged automatically) or an s3:// URI the engine can read. | | params | object | No | - | - | Options for the selected capability, as a JSON object (omit for sensible defaults; each capability documents its own schema). Examples: transcode {"vcodec":"h264","crf":23,"container":"mp4"} \| trim {"start":5,"duration":10} \| scale {"width":1280,"height":-2} \| extract_audio {"format":"mp3","sample_rate":16000,"mono":true} \| reframe {"aspect":"9:16","mode":"crop"} \| concat {"width":1280,"height":720} \| watermark {"x":10,"y":10} \| silence_remove {"ranges":[{"start":0,"end":12.5}]}. Most media-producing capabilities accept "container": mp4 (default), webm, or mkv. | | argv | array | No | - | - | Raw ffmpeg argument vector for mode=run_ffmpeg. argv[0] MUST be "ffmpeg" (or "ffprobe"). Use {input}/{input0},{input1}.. and {output} placeholders; the engine substitutes real paths. Literal URLs/protocol schemes inside argv are rejected at submit; run_ffmpeg access is a per-organization beta grant. | | output_format | string | No | mp4 | mp4, webm, mkv, mov, gif, mp3, wav, m4a, jpg, png, vtt, hls, dash | Output container/extension. Applies to mode=run_ffmpeg, where it names {output}'s extension (hls yields .m3u8, dash yields .mpd; unknown or empty falls back to mp4). mp4: default, widest playback. webm/mkv/mov: alternative video containers. gif: animated image. mp3/wav/m4a: audio-only. jpg/png: still image. vtt: WebVTT text. In mode=capability the operation's own params (container/format) decide the output - leave this at mp4. | ## Example Request ```bash curl -X POST https://api.eachlabs.ai/v1/prediction/ \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "eachlabs-video-api", "input": {} }' ``` ## Output Schema Response returned by `GET /v1/prediction/{id}` when the job completes: ```json { "status": "success", "predictionID": "string", "output": "string (URL of generated video)", "metrics": { "predict_time": "number (seconds)" } } ``` ## Polling ```bash curl https://api.eachlabs.ai/v1/prediction/{PREDICTION_ID} \ -H "Authorization: Bearer YOUR_API_KEY" ``` | Status | Meaning | |--------|---------| | `processing` | Still running — poll again | | `success` | Done — read `output` | | `error` | Failed — read `message` / `details` | ## Webhook (alternative to polling) Pass `"webhook_url": "https://your.host/path"` in the create request. Eachlabs POSTs this payload when the job ends: ```json { "exec_id": "prediction-uuid", "status": "succeeded", "output": "https://...", "error": "" } ``` `status` is `"succeeded"` or `"failed"`. `exec_id` equals the `predictionID` from create. Return 2xx within 30 seconds. ## Errors Error body: `{ "status": "error", "message": "...", "details": "..." }` | Code | Meaning | |------|---------| | `400` | Invalid input | | `401` | Missing / invalid `Authorization` bearer token | | `404` | Unknown model or prediction id | | `429` | Rate limit — 100 creates / min, 10 concurrent per key | | `5xx` | Retry with backoff | ## Usage Notes - API Base URL: `https://api.eachlabs.ai/v1` - Authentication: send `Authorization: Bearer YOUR_API_KEY`. Generate a key from the Eachlabs dashboard at https://www.eachlabs.ai/dashboard/api-keys. - File-typed parameters (`*_url`, `image_url`, `video_url`, `audio_url`, etc.) accept publicly-reachable HTTPS URLs only. Upload your asset first (GCS / S3 / your CDN) and pass the resulting URL. Data-URIs and localhost URLs are rejected. - For structured parameters (arrays / objects) send real JSON values, not stringified payloads. - Monetary values are reported in USD; per-token / per-megapixel rates may be billed in micro-cents internally. - Prefer `webhook_url` over polling for long-running predictions — see the Webhook Callback section.