A standalone CLI for the OpusClip API — submit a video, watch it render, download the clips. Scriptable, agent-friendly, and at home in any terminal.
Go Report Card, codecov, and the release/version badges activate once the repository is public.
opusclip wraps the OpusClip API
(https://api.opus.pro) behind one consistent interface, delivered as a single
static binary. It turns long-form videos into short clips from the command line:
- Creators / editors — clip a video URL and pull the results without opening the app.
- Developers / integrators — script the create→render→download pipeline, pipe JSON, wire CI jobs.
- AI / agent power users — drive clipping non-interactively with stable
--jsonoutput and exit codes.
Design north star: feel like gh, stripe, and sentry-cli — predictable
noun-verb commands, great --help, machine-readable output in pipes,
human-readable in a TTY, first-class auth, and a stage-stepper for long-running
renders.
- Install
- Quickstart
- Commands
- Output & scripting
- Authentication
- Configuration
- Exit codes
- Known gaps & roadmap
- Development
- License
# Homebrew (macOS/Linux)
brew install tdeschamps/tap/opusclip
# Shell installer (downloads the latest signed release binary)
curl -fsSL https://raw.githubusercontent.com/tdeschamps/opusclip-cli/main/install.sh | sh
# From source (Go 1.25+)
go install github.com/tdeschamps/opusclip-cli/cmd/opusclip@latestPrebuilt, signed binaries for darwin/{amd64,arm64}, linux/{amd64,arm64}, and
windows/amd64 are attached to every release.
API access requires a qualifying OpusClip plan (Pro/Max/Enterprise, currently in beta). Get a key from the dashboard.
# 1. Authenticate (paste a key interactively, or pipe it in CI)
opusclip auth login # paste a key from clip.opus.pro/dashboard
echo "$OPUSCLIP_API_KEY" | opusclip auth login --with-token
opusclip auth status
# 2. Clip a video and block until the clips are ready
opusclip clip create --url "https://youtu.be/LXvv6CbGg8A" --wait
# 3. …or do it in steps and capture the project id
pid=$(opusclip clip create --url "https://youtu.be/LXvv6CbGg8A" --json --jq '.[0].projectId')
opusclip clip watch "$pid" # live stage stepper to COMPLETE
# 4. List and download the generated clips
opusclip clips list --project "$pid"
opusclip clips download --project "$pid" --out ./clips
# 5. Raw escape hatch — anything the typed commands don't cover yet
opusclip api GET /api/clip-projects/"$pid"opusclip
├── auth login | logout | status | switch | token
├── config get | set | list | edit
├── profiles list | use
├── clip create | get | watch
├── clips list | download
├── api raw authenticated request escape hatch
├── info version, configuration & status (logo banner)
├── doctor connectivity & credential diagnostics
├── completion bash | zsh | fish | powershell
├── docs open the docs
├── update self-update
└── version
clip create accepts a video --url plus optional curation flags (--genre,
--lang, --keywords, --duration min:max, --start/--end,
--brand-template) and conclusion actions (--webhook, --email). Add --wait
to block until the render finishes.
- TTY → colorized, aligned tables. Piped/redirected → JSON.
- Override anytime with
-o table|json|csv|tsv|yamlor the--jsonshorthand. - Built-in
--jqfilter (powered by gojq; no externaljqneeded):opusclip clips list --project P1 --json --jq '.[].uriForExport'. --columns id,titleto pick/order columns for tables and CSV.- Long-running renders show a stage stepper on stderr;
--wait/watchreturn a stable exit code by outcome (0complete,8stalled,124timeout).
$ opusclip clips list --project P1
ID TITLE DURATION GENRE SCORE CREATED
P1.c1 Best Moment 00:30 podcast 87 2026-06-17T10:05:00Z
$ opusclip clips list --project P1 --json --jq '.[].uriForExport'
https://storage.googleapis.com/...opusclip resolves the key in this order: --api-key/--token flag →
OPUSCLIP_API_KEY/OPUSCLIP_TOKEN env → stored credential for the active
profile. Secrets are stored in the OS keychain when available (macOS
Keychain, Windows Credential Manager, libsecret/kwallet), with a 0600 file
fallback. Set OPUSCLIP_NO_KEYRING to skip the keychain and persist to the
0600 file — handy in CI, headless shells, or on macOS where the keychain can
pop an interactive prompt.
Keys are never printed back — opusclip auth status shows only a masked
fingerprint. OpusClip authenticates with an API key only (no OAuth). Multi-org
users can pass --org <id> or set OPUSCLIP_ORG_ID (sent as x-opus-org-id).
Config lives at ~/.config/opusclip/config.toml (XDG-respecting;
%APPDATA%\opusclip\config.toml on Windows). Any setting resolves
flag → env var → profile → built-in default.
active_profile = "default"
[profiles.default]
base_url = "https://api.opus.pro"
org_id = ""
output = "table"
default_limit = 50Manage it with opusclip config get/set/list/edit and opusclip profiles list/use. Relevant env vars: OPUSCLIP_API_KEY, OPUSCLIP_TOKEN,
OPUSCLIP_PROFILE, OPUSCLIP_BASE_URL, OPUSCLIP_ORG_ID, OPUSCLIP_OUTPUT,
OPUSCLIP_NO_KEYRING, OPUSCLIP_NO_UPDATE_NOTIFIER.
A Claude Code skill ships with this repo so agents drive the CLI efficiently
(the create→watch→download flow, --wait/--exit-status semantics, --json/--jq
idioms). It loads automatically inside this checkout. To get it in your own
projects:
/plugin marketplace add tdeschamps/opusclip-cli
/plugin install opusclip-cli@opusclip| Code | Meaning | Code | Meaning |
|---|---|---|---|
0 |
success | 5 |
not found (404) |
1 |
generic error | 6 |
rate limited (429) |
2 |
usage / bad flags | 7 |
validation (422) |
3 |
auth required (401) | 8 |
upstream / server / STALLED |
4 |
forbidden (403, incl. monthly cap) | 124 |
operation timed out |
v0.1 deliberately ships the core clip workflow. The following are not in v0.1 (documented here so there are no surprises):
- No
clip list(list-all-projects) — the public API exposes no project-list endpoint. Track theprojectIds you create. (v0.2 if an endpoint appears.) - No local file upload —
clip createtakes a--urlonly; the upload endpoint isn't in the public spec. (v0.2.) - Virality/judge scores are best-effort — surfaced only when the live API returns them (they're absent from the public spec).
- Webhook payloads are opaque —
--webhookregisters the URL; the delivered payload contract isn't modeled. - Out of scope (v0.1): collections, brand-template management, social posting, censor jobs, AI thumbnails, transcripts.
Built test-first in Go behind interface seams (see
ARCHITECTURE.md and CONTRIBUTING.md).
make test # go test -race ./...
make cover # coverage profile + total (fails under the 90% gate)
make lint # golangci-lint
make fmt # gofumpt + goimports
make build # ./bin/opusclipThe CI gate runs gofumpt, golangci-lint, go vet, govulncheck, the full
race-enabled test suite (unit + testscript e2e), and a cross-compile matrix.
MIT © Thomas Deschamps