Skip to main content

1. Create an account

Sign up at roughy.ai and verify your email.

2. Generate an API key

In the dashboard, navigate to API keys and create a new key. Treat it like a password — it grants full access to your account.

3. Verify the key

Every Roughy endpoint accepts a Bearer token in the Authorization header. A simple sanity check is to read your credit balance:
curl https://api.roughy.ai/v1/credits/balance \
  -H "Authorization: Bearer $ROUGHY_API_KEY"
A JSON response with a balance field means you’re set.

4. Cut and render your first video

The end-to-end shape is project → upload → cut → render → download. You’re charged once — per source minute (rounded up), after the asset is processed (see Credit ledger). Everything after that — the cut, the render — is free.

Create a project

A project is the container for the work you’re about to do.
PROJECT_ID=$(curl -sf https://api.roughy.ai/v1/projects \
  -H "Authorization: Bearer $ROUGHY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Episode 42"}' | jq -r .id)

Upload an asset

Upload an audio or video source via the create-asset → TUS pattern. POST /v1/assets creates the asset and opens its upload in one call — size_bytes is the file size; language (an optional spoken-language hint) is set here and immutable:
POST https://api.roughy.ai/v1/assets
Content-Type: application/json

{ "project_id": "<PROJECT_ID>", "size_bytes": 524288000, "language": "de" }
The response body is the asset; the TUS transfer URL comes back in the Location header — hand it to your TUS client to stream the file. See the Upload an asset guide for ready-to-paste clients. When the upload finalises, the asset moves to processing; once Roughy finishes preparing it and the per-minute charge settles, it becomes ready (cuttable and renderable).

Trigger a cut

A cut is the kept-segment plan — Roughy keeps the spans worth keeping and drops filler, restarts, and off-topic spans. Pass the asset id, plus an optional reference script in the body:
curl https://api.roughy.ai/v1/cuts \
  -H "Authorization: Bearer $ROUGHY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "asset_id": "<ASSET_ID>" }'
If the asset isn’t cuttable yet you’ll get 409 with a typed code: asset_processing (still being prepared — back off for the Retry-After seconds and retry), asset_payment_required (top up your balance), or asset_failed. Otherwise you get a cut — a freshly created one starts in state: pending (201); re-posting the same asset_id + script returns the existing cut (200). Poll GET /v1/cuts/{cut_id} until state is completed.

Render the result

A render applies a cut to the media and produces a video (mp4 / mov) or audio (m4a / mp3) output. Pass cut_id to apply that cut; omit it to render the full source:
curl https://api.roughy.ai/v1/renders \
  -H "Authorization: Bearer $ROUGHY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "asset_id": "<ASSET_ID>",
    "cut_id": "<CUT_ID>",
    "output": { "format": "mp4", "resolution": "1080p" }
  }'
Poll GET /v1/renders/{render_id} until state is completed; the response then carries a short-lived signed download_url. Fetch the bytes from there and you’re done.

Skip the polling

Instead of polling, register a webhook endpoint for cut.completed and render.completed and let Roughy push you the terminal events.

Prefer your own editor?

Skip the render and export the cut straight to your NLE: GET /v1/cuts/{cut_id}/export?format=xmeml (also fcpxml, edl, otio).

Next steps