PodcastsToText
Transcriptions

Create a transcription

POST one URL (podcast, YouTube, TikTok or a direct audio file) and get an id back immediately.

POST/api/v1/transcriptionsscope: transcriptions:write

Send one URL. We work out what it is, resolve it to audio, and start transcribing. The response is immediate and carries an id.

Request body

FieldTypeRequiredDescription
urlstringYesA Spotify or Apple Podcasts episode link, a YouTube or TikTok URL, or a direct audio file. Required unless you send audio_url.
audio_urlstringNoA direct audio file you have already resolved yourself. Skips resolution entirely.
titlestringNoOverrides the title we resolve from the platform.
languagestringNoISO code such as en or de. Omitted means autodetect.
speaker_labelsbooleanNoLabel distinct speakers. Defaults to true. Paid plans only.
duration_secondsnumberNoOnly with a direct audio_url, where the file would otherwise be probed.

Response

202 Accepted
{
  "id": "9f3c8e21-4b7a-4c19-9f2e-1d8a6c3b5e07",
  "status": "processing",
  "source_type": "spotify",
  "message": "Transcription started. It usually takes a fraction of the episode length.",
  "next_actions": [
    "GET /api/v1/transcriptions/9f3c8e21-… to check status: poll every 5-10s until status is \"completed\"",
    "GET /api/v1/transcriptions/9f3c8e21-…?include=text once completed"
  ]
}

Branch on status, never on the status code. Every create returns 202, even when the work is already done: a YouTube video with a caption track is read inline and comes back "status": "completed". That is a property of the video, not of your request.

What can go wrong

StatusCodeWhat happened
400bad_requestNo url or audio_url, malformed JSON, or a link that is not media and not a recognised platform.
402insufficient_creditsFewer credits than the episode needs. GET /api/v1/usage shows the balance.
403plan_requiredThis plan has no API write access. Distinct from 402, which means an empty balance.
422source_unavailableUsually a YouTube video with no caption track.
429too_many_in_flightAt the plan’s concurrency cap. Not a rate limit: waiting for a job to finish is the fix, not backing off.
429rate_limitedA genuine rate limit. Read Retry-After.
502source_unavailableThe media could not be fetched. For a TikTok this is usually our extractor being busy. Retry once.

Concurrency

Each plan bounds how many transcriptions may run at once; see rate limits for the numbers. To work through a back catalogue, keep a window open: poll GET /api/v1/transcriptions?status=processing and start a new one each time the count drops.