Transcription for AI agents.

Give your agent a URL or a file and get back transcripts, subtitles, chapters, quotes with timestamps and platform captions. Every call returns JSON. Same engine, wallet and API key as the transcribe.so API and MCP server.

Use any agent: Claude Code/Claude (claude.ai and Desktop)/Codex/Cursor/ChatGPT/Gemini CLI/OpenClaw and skills.sh agents/Any MCP client

Rule for the agent: Check the price before creating a job. Stay within the user's authorized budget; ask before exceeding it or starting another paid attempt. Cap the spend twice: set a monthly limit on the API key, and send max_charge_usd on each job. A job priced above the ceiling is refused before any money moves, and quotes are always free.

Fastest path

Paste one line with your key into Claude Code. The agent reads the setup skill, stores the key in its own config, and verifies the account; the skill carries the steps for Codex, Cursor and shell agents. Details and troubleshooting on the Claude Code page.

Set up https://transcribe.so/SKILL.md with this transcribe.so API key: tsk_live_...

Three ways to install

One repo ships all three: an agent skill, a Claude Code plugin, and a CLI. Pick the one that matches your agent runtime. Each needs a TRANSCRIBE_API_KEY from your settings.

Agent skill

For any agent that reads SKILL.md files (skills.sh, OpenClaw, and similar).

npx skills add shsunmoonlee/transcribe-agent

Claude Code plugin

Adds transcription skills and commands to Claude Code.

/plugin marketplace add shsunmoonlee/transcribe-agent
/plugin install transcribe-so@transcribe-agent

CLI

A transcribe-so binary for scripts, cron jobs, and any agent that can run a shell.

npm install -g transcribe-so
export TRANSCRIBE_API_KEY=tsk_live_...

The core flow

Quote first (free), create (charges the wallet), wait, then read the result. Every command prints pure JSON to stdout, so the output pipes straight into jqor your agent's tool loop. The job id is the one returned by create.

$ transcribe-so quote --source youtube --url https://youtu.be/RdAY3DjSr3A
{ "retail_usd": 0.35, "billed_minutes": 21, "pipeline_code": "standard", ... }

$ transcribe-so create --source youtube --url https://youtu.be/RdAY3DjSr3A
{ "id": 4821, "status": "processing", "stage": "queued", ... }

$ transcribe-so wait 4821
{ "id": 4821, "status": "completed", ... }

$ transcribe-so result 4821 > transcript.json

Or do all four in one call with a spend cap: transcribe-so run --source youtube --url ... --max-usd 2. The CLI refuses locally if the quote exceeds the cap, before any money moves.

What your agent actually runs

You ask in plain language. The agent turns it into the calls below, with a hard price ceiling: run quotes first and refuses to create the job if the quote is over --max-usd.

You: Transcribe this episode and give me Instagram captions, under $3.

$ transcribe-so quote --source youtube --url https://youtu.be/RdAY3DjSr3A
$ transcribe-so run --source youtube --url https://youtu.be/RdAY3DjSr3A --max-usd 3
$ transcribe-so captions 4821 --for instagram

Ask for the output you actually want

The transcript itself is one endpoint. Beyond it, three different things get called "captions", and they are three different endpoints with three different bodies. Pick the one your task needs.

  • Transcript text — GET /api/v1/transcriptions/:id/transcript returns the raw body as text/plain or text/markdown. Speaker labels and timestamps are both on by default; pass speaker_labels=false or timestamps=false to strip them. Nothing is truncated.
  • Social post text — GET /api/v1/transcriptions/:id/timestamps drafts the caption or chapter list you paste into a post.
  • Timed subtitles — GET /api/v1/transcriptions/:id/subtitles returns an SRT or VTT file for a video editor or player.
  • Captioned video — POST /api/v1/transcriptions/:id/clips renders a shareable MP4 with the captions burned in.
  • Who said what — GET /api/v1/search?q=... returns matching segments with speaker, start and end times, and a deep link.
# the transcript text, speaker-labelled, with timestamps
curl -sS -H "Authorization: Bearer $TRANSCRIBE_API_KEY" \
  "https://transcribe.so/api/v1/transcriptions/4821/transcript?format=txt&speaker_labels=true&timestamps=true"

# who said what, and when
curl -sS -H "Authorization: Bearer $TRANSCRIBE_API_KEY" \
  "https://transcribe.so/api/v1/search?q=pricing&limit=10"

Command reference

CommandWhat it does
transcribe-so auth:statusCheck that the API key works and which account it belongs to
transcribe-so meAccount, plan, and wallet balance
transcribe-so capabilitiesOne JSON object: account, pipeline catalog, every accepted format value, and the exit codes
transcribe-so pipelinesPipeline catalog with per-minute pricing
transcribe-so quotePrice a job before creating it. Free, does not start anything
transcribe-so createSubmit a transcription. Charges the wallet, returns the job id. --max-charge-usd caps the charge server-side
transcribe-so wait <id>Block until the job completes or fails (server long-poll)
transcribe-so result <id>Transcript with chapters and cited Q&A; add --include segments for speaker-labelled, timestamped segments
transcribe-so runquote, then create, wait, and result in one call. Requires --max-usd, also sent as the server-side ceiling
transcribe-so listRecent transcriptions
transcribe-so get <id>Status and metadata for one transcription
transcribe-so delete <id> --yesDelete a transcription. Irreversible
transcribe-so retry <id> --yesRetry a failed job. Re-charges from scratch
transcribe-so upload <file>Upload a local file, get an upload_id for quote and create
transcribe-so transcript <id>The complete transcript as raw text or Markdown (--format txt|md). Never capped
transcribe-so subtitles <id>Subtitle file (SRT/VTT) to stdout, raw
transcribe-so captions <id> --for <dest>Paste-ready caption or chapter list for instagram, x, threads, linkedin, youtube, spotify, apple_podcasts, markdown or plain, raw (--json for the envelope)
transcribe-so search <q>Who said what, and when: matching segments with speaker, times, and a link. Library-wide or --id scoped
transcribe-so ask <id> -qAsk a question about a transcript, get a cited answer

Destructive and re-charging commands require an explicit --yes. Exit codes separate auth, payment, and spend-cap failures so an agent knows whether to fix the key, top up, or raise --max-usd.

Every agent surface

The skill, plugin, and CLI sit on the same public API as everything else. If your agent speaks MCP or plain HTTP, connect directly.

Connect by runtime

Claude Code

Plugin or one MCP command.

claude mcp add --transport http transcribe https://transcribe.so/mcp
Claude (claude.ai and Desktop)

Settings, Connectors, Add custom connector, paste https://transcribe.so/mcp, then sign in. Works on every Claude plan (Free allows one custom connector). Claude transcribes public links; upload local files in the transcribe.so web app. On Team and Enterprise, an Owner adds it once for the organization. Add the connector.

Codex

Plugin or one MCP command.

codex mcp add transcribe --url https://transcribe.so/mcp
Cursor

Add to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global). OAuth on first use.

{"mcpServers":{"transcribe":{"url":"https://transcribe.so/mcp"}}}
ChatGPT

Use the public transcribe.so GPT, or add https://transcribe.so/mcp under Settings, Connectors, Developer mode (paid ChatGPT plans). Open the GPT.

Gemini CLI

One MCP command, or settings.json {"mcpServers":{"transcribe":{"httpUrl":"https://transcribe.so/mcp"}}}.

gemini mcp add --transport http transcribe https://transcribe.so/mcp
OpenClaw and skills.sh agents

Install the skill.

npx skills add shsunmoonlee/transcribe-agent
Any MCP client

Streamable HTTP at https://transcribe.so/mcp. OAuth, or an Authorization: Bearer tsk_live_... key.

Wire it into your agent

Create a key, export it, and your agent is transcribing in one command. Quotes are free, so it can always check the price before it spends.