Video URL transcript API

Transcribe a video straight from its URL

You pass a link, the API does the rest: source resolution, audio extraction, transcription, timestamped JSON. No media ever touches your servers.

request
# 1. Post the video URL
curl -X POST https://api.techtuel.com/v1/transcriptions \
  -H "Authorization: Bearer $TECHTUEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "source_url": "https://example.com/product-webinar" }'
# => 202 { "id": "job_7c1a", "status": "processing" }

# 2. Poll the job until it completes
curl https://api.techtuel.com/v1/transcriptions/job_7c1a \
  -H "Authorization: Bearer $TECHTUEL_API_KEY"
response
{
  "id": "job_7c1a",
  "status": "completed",
  "title": "Product webinar — shipping v3",
  "language": "en",
  "minutes": 41,
  "source_kind": "url",
  "source_url": "https://example.com/product-webinar",
  "created_at": "2026-07-21T09:30:00Z",
  "transcript": "Thanks everyone for joining…",
  "segments": [
    { "start_seconds": 0, "text": "Thanks everyone for joining" },
    { "start_seconds": 5.4, "text": "let's start with the roadmap" }
  ]
}

The hidden cost of video transcription is almost never the transcription itself — it is everything that comes before it. Downloading the video, following redirects and signed URLs, pulling the audio track out with FFmpeg, re-encoding it into an accepted format, storing it while the job runs, cleaning up afterwards, and doing it all again when a binary changes version. That is an entire media pipeline nobody wants to maintain just to end up with text.

Techtuel takes the link instead. You POST to /v1/transcriptions with a source_url field, and the API resolves whatever sits at the other end: a video platform, a web page with a player, a direct video file. It extracts the audio, transcribes it, and hands you back a job. Your server never touches a byte of media — no egress bandwidth, no scratch disk, no FFmpeg in your Docker image.

The model is plain REST, and that is deliberately boring. POST /v1/transcribe hands the transcript back in the same response; when the media is long enough that the wait window elapses, it returns 202 with an id and status processing, and you read GET /v1/transcriptions/{id} until it says completed or failed. The JSON envelope is stable: id, status, title, language, minutes, source_kind, transcript and segments, where each segment is a start_seconds / text pair. Append ?format=txt, srt or vtt if you would rather have the output already formatted.

Why this API

No media pipeline

No yt-dlp, no FFmpeg, no scratch bucket. The video is never downloaded to your side — all you send is a string.

A predictable REST job

POST → 202 + id → GET until completed. No WebSocket, no mandatory SDK: two HTTP calls and a typed JSON body.

Title resolved for you

The title field gives you the real video name without a second call to a metadata API, so your job list is readable immediately.

Pricing you can read

Free100 credits/month (~50 min of video), no credit card
Pro2000 credits/month (~1000 min), 120 req/min per key

Frequently asked questions

Do I have to download the video before calling the API?+

No. You send the URL in the source_url field and the API fetches the media itself. No file passes through your infrastructure.

What is the difference between source_url and audio_url?+

source_url points at a page or video to resolve (a platform link, a web page, a share URL). audio_url points at a directly downloadable audio file. Both produce the same job.

How long does a transcription take?+

It scales with the length of the media. On POST /v1/transcribe, short media — or a source already transcribed and served from cache — comes back in the response itself. Past the wait window you get a 202 with a job id: processing continues, and GET /v1/transcriptions/{id} returns completed with the text, or failed with an error field.

Can I get subtitles directly?+

Yes. Adding ?format=srt or ?format=vtt when you read the job returns a ready-to-use subtitle file built from the segments.

What if the URL is gated or offline?+

The job ends in status failed with a message in the error field. You can re-run it with POST /v1/transcriptions/{id}/retry once the source is reachable again.

Other ways to use the API

Free trial, no credit card

Generate an API key and transcribe your first source in under a minute. A free monthly quota lets you test under real conditions.

Start with the API