Transcript.land for developers
If you're building anything that needs text out of a video — a research pipeline, a content tool, an agent that watches links — the annoying part isn't transcription itself, it's the branching: does this video have captions or not, and now you have two code paths to maintain.
The problem
Caption-scraping libraries only do one thing: read a caption track that already exists. The moment a video doesn't have one — disabled by the uploader, never auto-generated, a platform that doesn't support it — the call fails, and you're stuck either handling that as an error or standing up your own ASR pipeline (audio extraction, a speech-recognition model, a job queue for long files, chunking and stitching) just to keep your feature working for everyone.
How it helps
Transcript.land is one API call. If the source has captions, you get the transcript back directly. If it doesn't, the same call returns a job you poll — the transcript, once it's ready, has the same shape as the direct response. Your code doesn't need to know or care which path ran.
curl -X POST https://api.transcript.land/v1/transcript \
-H "Authorization: Bearer $TRANSCRIPT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://youtu.be/dQw4w9WgXcQ", "format": "json"}'When captions exist, that returns the transcript directly. When they don't,
you get a 202 with a job to poll instead:
{ "job_id": "a1b2c3...", "status": "queued" }curl https://api.transcript.land/v1/jobs/a1b2c3... \
-H "Authorization: Bearer $TRANSCRIPT_API_KEY"Poll GET /v1/jobs/{job_id} every couple of seconds until status is
done (or error) and the transcript comes back in the response.
Surfaces
- REST API —
POST /v1/transcriptplus the jobs endpoint above for the async path. Full reference is in the docs. - CLI —
brew install ziqorg/tap/transcript, thentranscript loginonce to link your account, thentranscript get <url>. It handles the polling for you, so an ASR fallback looks the same as a direct hit from the command line. - MCP connector —
https://transcript.land/mcp, listed in the official MCP Registry, for wiring transcription into an agent without hand-rolling the HTTP calls.
A realistic workflow
import requests
resp = requests.post(
"https://api.transcript.land/v1/transcript",
headers={"Authorization": "Bearer sk_live_..."},
json={"url": url, "format": "json"},
)
if resp.status_code == 202:
job_id = resp.json()["job_id"]
# poll GET /v1/jobs/{job_id} until status == "done"
else:
transcript = resp.json()That's the whole branch you need — everything downstream (rendering, storage, search indexing) can consume one normalized shape regardless of which path produced it.
What you get
- One request shape for both the instant-caption path and the AI-transcription fallback, with segment-level timestamps either way.
- Any source: YouTube, TikTok, X, Instagram, Bilibili, Facebook, RedNote, direct audio/podcast URLs, and file uploads.
- Any language, without a separate parameter for which pipeline to use.
- Exports: TXT, SRT, VTT, Markdown, JSON — set via
formatin the request, or pull JSON and convert downstream. - An MCP connector, if the consumer is an agent rather than your own backend.
What it doesn't do
It doesn't do speaker diarization, translation, or summarization — it's scoped to getting accurate, timestamped text out of a video or audio source reliably, in one call. It's also not the cheapest API in this space if raw price-per-minute is your only constraint; where it tends to save engineering time is not having to build and maintain the no-captions branch yourself.
Try it
The free tier is 15 minutes of video a month, which is enough to wire up the integration and confirm the response shape end to end before you commit to anything. Get an API key to start, or see plans and pricing for volume and rate limits.