Endpoints
Transcripts
Create, list, read, search, export, and delete transcripts. Full request and response schemas.
Transcripts turn pre-recorded audio or video into text with word timings, confidence scores, and optional speaker labels. Create one from a public audio_url or from an upload_id produced by the upload flow, then poll until it completes.
Status lifecycle
| Status | Meaning |
|---|---|
| queued | Accepted and waiting to start. |
| processing | The audio is being transcribed. This is the usual status right after creation. |
| completed | Text, words, utterances, confidence, and duration are populated. |
| error | Processing failed; the error field explains why. |
Poll GET /v2/transcripts/{transcript_id} until status is completed or error, or register a webhook_url at creation to receive a callback on the terminal status. Derived reads (sentences, paragraphs, word search, subtitles) return 409 not_ready before completion.
The transcript object
| Field | Type | Description |
|---|---|---|
| id | string | Unique transcript id. |
| status | string | queued, processing, completed, or error. |
| model | string or null | Model id the transcript was created with. |
| title | string or null | Display title. Defaults to the upload filename when created from an upload. |
| language_code | string or null | Language you requested, or null when automatic detection was used. |
| speaker_labels | boolean | Whether speaker diarization was requested. |
| text | string or null | Full transcript text. null until completed. |
| words | array or null | Per-word objects with text, start, end (milliseconds), confidence (0 to 1), and speaker when diarization is on. |
| utterances | array or null | Speaker turns with speaker, text, start, end, confidence, and their words. Populated when speaker_labels is true. |
| confidence | number or null | Overall confidence between 0 and 1. |
| audio_duration_sec | integer or null | Duration of the source audio in seconds. This is the quantity your usage is metered on. |
| summary | string or null | Generated summary. Null unless summarization was requested. |
| chapters | array or null | Auto-detected chapters with titles and timings. Null unless auto_chapters was requested. |
| entities | array or null | Detected entities such as people, places, and organizations. Null unless entity_detection was requested. |
| sentiment_results | array or null | Per-segment sentiment results. Null unless sentiment_analysis was requested. |
| content_safety | object or null | Content safety report. Null unless content_moderation was requested. |
| webhook_url | string or null | The notification URL registered at creation, echoed back. Null when none was set. |
| error | string or null | Failure reason when status is error. |
| created_at | string | ISO 8601 creation time. |
| completed_at | string or null | ISO 8601 completion time. |
Create a transcript
/v2/transcriptsSubmit audio for transcription. Returns 201 with the new transcript.Request body
| Field | Type | Default | Description |
|---|---|---|---|
| audio_url | string or null | null | Direct, publicly reachable URL of the audio or video file. Required unless upload_id is set; omitting both fails validation with 422. |
| upload_id | string or null | null | Id of a completed upload. Takes precedence over audio_url when both are sent. |
| model | string | whisper-voicekit-best | Pre-recorded model id: whisper-voicekit-best or whisper-voicekit-fast. Unknown ids return 400 unknown_model. See Models. |
| language_code | string or null | null | Language of the audio, for example en, es, pt. Leave null to auto-detect the language. |
| language_codes | array of strings or null | null | Expected languages for mixed-language audio. When set it overrides language_code and disables auto-detection. |
| speaker_labels | boolean | false | Detect speakers and label every utterance and word. |
| auto_chapters | boolean | false | Segment the audio into chapters. Results are returned in the chapters field of the completed transcript. |
| entity_detection | boolean | false | Detect named entities such as people, places, and organizations. Results are returned in entities. |
| sentiment_analysis | boolean | false | Score sentiment across the speech. Results are returned in sentiment_results. |
| summarization | boolean | false | Generate a summary. Returned in the summary field. |
| content_moderation | boolean | false | Flag sensitive content. The report is returned in content_safety. |
| pii_redaction | boolean | false | Redact personally identifiable information from the transcript text. |
| profanity_filter | boolean | false | Mask profanity in the transcript text. |
| medical_mode | boolean | false | Use the medical domain model for clinical vocabulary. Applies when a single explicit language_code that supports it is set (en, es, fr, de). |
| keyterms_prompt | array of strings or null | null | Domain-specific words and phrases to boost recognition accuracy. The first 1000 entries are used. |
| webhook_url | string or null | null | Public http(s) URL (up to 2048 characters) that receives a JSON notification when the transcript reaches a terminal status. Non-http(s) values fail validation with 422; private, loopback, and cloud metadata hosts are rejected with 400 invalid_webhook_url. See Webhook notifications below. |
| title | string or null | null | Display title. Defaults to the upload filename when created from an upload. |
| estimated_duration_sec | integer or null | null | Estimated audio length in seconds (minimum 1). Used for a pre-flight credit check: if the estimated cost exceeds your remaining free credit, the request fails early with 402 v2_billing_required instead of mid-job. |
summarization fills summary, auto_chapters fills chapters, entity_detection fills entities, sentiment_analysis fills sentiment_results, and content_moderation fills content_safety. pii_redaction and profanity_filter change the returned text itself. For ad-hoc question answering over a finished transcript, use Speech intelligence.Response
Returns 201 with a transcript object. The status is normally processing at this point; poll the get endpoint until it completes, or register a webhook_url to be notified on completion.
Errors
| Status | Code | When |
|---|---|---|
| 400 | unknown_model | model is not a catalog id. |
| 400 | invalid_webhook_url | webhook_url is not a public http(s) URL: private, loopback, and cloud metadata hosts are rejected. |
| 402 | v2_billing_required | Free credit exhausted, or the estimated_duration_sec estimate exceeds the remaining balance. |
| 404 | not_found | upload_id does not exist or belongs to another account. |
| 422 | (validation) | Neither audio_url nor upload_id was provided, webhook_url is not an http(s) URL, or another field failed validation. |
curl -X POST https://api.realtimevoicekit.com/v2/transcripts \
-H "Authorization: Bearer rtvk_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"audio_url": "https://example.com/podcast-episode.mp3",
"model": "whisper-voicekit-best",
"speaker_labels": true,
"language_code": "en"
}'{
"id": "tr_5c8e2f91d0",
"status": "processing",
"model": "whisper-voicekit-best",
"title": null,
"language_code": "en",
"speaker_labels": true,
"text": null,
"words": null,
"utterances": null,
"confidence": null,
"audio_duration_sec": null,
"summary": null,
"chapters": null,
"entities": null,
"sentiment_results": null,
"content_safety": null,
"webhook_url": null,
"error": null,
"created_at": "2026-07-22T14:03:11Z",
"completed_at": null
}Webhook notifications
When a webhook_url is registered at creation, the API sends an HTTP POST to that URL once the transcript reaches a terminal status. The payload is intentionally minimal; fetch the full transcript with GET /v2/transcripts/{transcript_id} when the notification arrives. Polling remains fully supported, with or without a webhook.
{
"event": "transcript.completed",
"transcript_id": "tr_5c8e2f91d0",
"status": "completed"
}| Field | Type | Description |
|---|---|---|
| event | string | transcript.completed on success, transcript.error on failure. |
| transcript_id | string | The transcript that reached a terminal status. |
| status | string | completed or error, matching the event. |
Delivery behavior
- Requests time out after 10 seconds and redirects are not followed. Respond quickly with a
2xxstatus and do any heavy work asynchronously. - A
5xxresponse or a network failure is retried with backoff. A4xxresponse is treated as a permanent failure and is not retried. - Retries reuse the same notification for the same transcript and status, so make your handler idempotent on
transcript_idplusevent. - The URL must be publicly reachable over http or https. Private, loopback, and cloud metadata addresses are rejected at creation with
400 invalid_webhook_url.
List transcripts
/v2/transcriptsList your API-created transcripts, newest first| Query param | Type | Default | Description |
|---|---|---|---|
| limit | integer, 1 to 200 | 50 | Rows per page. |
| offset | integer, 0 or more | 0 | Rows to skip. |
Returns { "data": [ …transcript objects… ] }. Only transcripts created through the API are listed; transcripts created in the web workspace are separate.
curl "https://api.realtimevoicekit.com/v2/transcripts?limit=10&offset=0" \
-H "Authorization: Bearer rtvk_your_api_key"Get a transcript
/v2/transcripts/{transcript_id}Fetch one transcript, including text and words once completed| Path parameter | Type | Description |
|---|---|---|
| transcript_id | string | The transcript id returned at creation. |
Returns the full transcript object. 404 not_found when the id does not exist or is not yours.
curl https://api.realtimevoicekit.com/v2/transcripts/tr_5c8e2f91d0 \
-H "Authorization: Bearer rtvk_your_api_key"Get sentences
/v2/transcripts/{transcript_id}/sentencesThe transcript split into sentences with timingsSplits the completed transcript into sentence segments. Requires status to be completed, otherwise 409 not_ready.
| Segment field | Type | Description |
|---|---|---|
| index | integer | Zero-based position of the segment. |
| text | string | Sentence text. |
| start | integer or null | Start of the first word in milliseconds. |
| end | integer or null | End of the last word in milliseconds. |
| confidence | number or null | Average word confidence for the segment. |
| words | array or null | The word objects that make up the segment. |
curl https://api.realtimevoicekit.com/v2/transcripts/tr_5c8e2f91d0/sentences \
-H "Authorization: Bearer rtvk_your_api_key"Get paragraphs
/v2/transcripts/{transcript_id}/paragraphsThe transcript grouped into readable paragraphsGroups sentences into paragraphs and returns the same segment shape as the sentences endpoint, wrapped in data. Requires a completed transcript (409 not_ready otherwise).
curl https://api.realtimevoicekit.com/v2/transcripts/tr_5c8e2f91d0/paragraphs \
-H "Authorization: Bearer rtvk_your_api_key"Search words
/v2/transcripts/{transcript_id}/word-searchFind where specific words occur, with timestamps| Query param | Type | Description |
|---|---|---|
| q | string | Comma-separated search terms, up to 25. Matching is case-insensitive on whole words. |
| words | string | Alias of q; either parameter works. |
Requires a completed transcript. Omitting both parameters returns 400 missing_query.
| Response field | Type | Description |
|---|---|---|
| query | string | The terms that were searched, comma-joined. |
| total_matches | integer | Sum of match counts across all terms. |
| matches | array | One entry per term: text, count, and timestamps with start, end (milliseconds), and confidence per occurrence. |
curl "https://api.realtimevoicekit.com/v2/transcripts/tr_5c8e2f91d0/word-search?q=pricing,roadmap" \
-H "Authorization: Bearer rtvk_your_api_key"{
"query": "pricing, roadmap",
"total_matches": 3,
"matches": [
{
"text": "pricing",
"count": 2,
"timestamps": [
{ "start": 12040, "end": 12480, "confidence": 0.98 },
{ "start": 84200, "end": 84660, "confidence": 0.97 }
]
},
{ "text": "roadmap", "count": 1, "timestamps": [ { "start": 61500, "end": 61980, "confidence": 0.99 } ] }
]
}Export subtitles
/v2/transcripts/{transcript_id}/{fmt}Download the transcript as SRT or VTT subtitles| Path parameter | Type | Description |
|---|---|---|
| transcript_id | string | The transcript id. |
| fmt | string | srt or vtt (case-insensitive). Anything else returns 400 bad_format. |
Returns the subtitle file as plain text: application/x-subrip for SRT, text/vtt for VTT. Requires a completed transcript (409 not_ready).
curl -o captions.srt https://api.realtimevoicekit.com/v2/transcripts/tr_5c8e2f91d0/srt \
-H "Authorization: Bearer rtvk_your_api_key"Delete a transcript
/v2/transcripts/{transcript_id}Permanently delete a transcript. Returns 204.Deletes the transcript and its processed data permanently. Returns 204 No Content on success and 404 not_found when the id does not exist or is not yours. This cannot be undone.
curl -X DELETE https://api.realtimevoicekit.com/v2/transcripts/tr_5c8e2f91d0 \
-H "Authorization: Bearer rtvk_your_api_key"