Speaker identification, 100+ languages, word-level timestamps. Perfect for depositions, hearings, and interviews.
POST /voice/transcription
Vault Mode (Recommended)
Upload your audio to a vault, then transcribe with automatic result storage. The transcript is saved back to your vault when complete.
cURL
CLI
Typescript
Python
Go
# 1. Get upload URL
curl -X POST https://api.case.dev/vault/VAULT_ID/upload \
-H "Authorization: Bearer sk_case_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filename": "deposition.mp3", "contentType": "audio/mpeg", "auto_index": false}'
# 2. Upload file to the returned uploadUrl (PUT request)
# 3. Start transcription
curl -X POST https://api.case.dev/voice/transcription \
-H "Authorization: Bearer sk_case_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"vault_id": "VAULT_ID",
"object_id": "OBJECT_ID",
"speaker_labels": true
}'
casedev vault upload \
--id $VAULT_ID \
--filename "deposition.mp3" \
--content-type "audio/mpeg"
import Casedev from 'casedev' ;
const client = new Casedev ({ apiKey : 'sk_case_YOUR_API_KEY' });
// 1. Upload audio to vault
const upload = await client . vault . upload ( 'vault_abc123' , {
filename : 'deposition.mp3' ,
contentType : 'audio/mpeg'
});
// Upload file to upload.uploadUrl via PUT
// 2. Start transcription
const job = await client . voice . transcription . create ({
vault_id : 'vault_abc123' ,
object_id : upload . objectId ,
speaker_labels : true
});
console . log ( job . id ); // tr_xyz789
import casedev
client = casedev. Casedev ( api_key = 'sk_case_YOUR_API_KEY' )
# 1. Upload audio to vault
upload = client.vault. upload ( 'vault_abc123' ,
filename = 'deposition.mp3' ,
content_type = 'audio/mpeg'
)
# Upload file to upload.upload_url via PUT
# 2. Start transcription
job = client.voice.transcription. create (
vault_id = 'vault_abc123' ,
object_id = upload.object_id,
speaker_labels = True
)
print (job.id) # tr_xyz789
upload , _ := client . Vault . Upload ( ctx , vaultID , casedev . VaultUploadParams {
Filename : casedev . F ( "deposition.mp3" ),
ContentType : casedev . F ( "audio/mpeg" ),
})
// PUT file to upload.UploadURL via net/http
fmt . Println ( upload . ObjectID )
{
"id" : "tr_rvy731o5zxur0dg72sh3mjar" ,
"status" : "processing" ,
"vault_id" : "vault_abc123" ,
"source_object_id" : "obj_xyz789"
}
Get Results (Vault Mode)
cURL
CLI
Typescript
Python
Go
curl https://api.case.dev/voice/transcription/tr_rvy731o5zxur0dg72sh3mjar \
-H "Authorization: Bearer sk_case_YOUR_API_KEY"
casedev voice:transcription create \
--audio-url "https://storage.example.com/recording.mp3" \
--speaker-labels
const result = await client . voice . transcription . retrieve ( 'tr_rvy731o5zxur0dg72sh3mjar' );
if ( result . status === 'completed' ) {
console . log ( result . result_object_id ); // Transcript stored here
console . log ( result . word_count ); // 594
console . log ( result . confidence ); // 97
// Download transcript from vault
const transcript = await client . vault . objects . download (
result . vault_id ,
result . result_object_id
);
}
result = client.voice.transcription. retrieve ( "tr_rvy731o5zxur0dg72sh3mjar" )
if result.status == "completed" :
print (result.result_object_id) # Transcript stored here
print (result.word_count) # 594
print (result.confidence) # 97
# Download transcript from vault
transcript = client.vault.objects. download (
result.vault_id,
result.result_object_id
)
result , _ := client . Voice . Transcription . Get ( ctx , "tr_rvy731o5zxur0dg72sh3mjar" )
if result . Status == "completed" {
fmt . Println ( result . ResultObjectID )
content , _ := client . Vault . Objects . Download ( ctx , result . VaultID , result . ResultObjectID )
// content is *http.Response with file body
}
{
"id" : "tr_rvy731o5zxur0dg72sh3mjar" ,
"status" : "completed" ,
"vault_id" : "vault_abc123" ,
"source_object_id" : "obj_xyz789" ,
"result_object_id" : "obj_abc456" ,
"audio_duration" : 238 ,
"word_count" : 594 ,
"confidence" : 97
}
Vault Mode Benefits:
Transcript automatically saved to your vault
No webhook setup required
Simpler polling with result_object_id
Audio stored securely in your vault
Direct URL Mode
For audio hosted elsewhere, provide a public URL directly.
cURL
CLI
Typescript
Python
Go
curl -X POST https://api.case.dev/voice/transcription \
-H "Authorization: Bearer sk_case_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"audio_url": "https://storage.example.com/deposition.m4a",
"speaker_labels": true,
"auto_chapters": true
}'
casedev voice:transcription create \
--audio-url "https://storage.example.com/recording.mp3" \
--speaker-labels
import Casedev from 'casedev' ;
const client = new Casedev ({ apiKey : 'sk_case_YOUR_API_KEY' });
const job = await client . voice . transcription . create ({
audio_url : 'https://storage.example.com/deposition.m4a' ,
speaker_labels : true ,
auto_chapters : true
});
console . log ( job . id ); // Poll this for results
import casedev
client = casedev. Casedev ( api_key = 'sk_case_YOUR_API_KEY' )
job = client.voice.transcription. create (
audio_url = 'https://storage.example.com/deposition.m4a' ,
speaker_labels = True
)
print (job.id) # Poll this for results
job , _ := client . Voice . Transcription . New ( ctx , casedev . VoiceTranscriptionNewParams {
AudioURL : casedev . F ( "https://storage.example.com/recording.mp3" ),
SpeakerLabels : casedev . F ( true ),
})
fmt . Println ( job . ID )
{
"id" : "474e21cf-fd65-45d4-97fd-87558f7caf9b" ,
"status" : "queued" ,
"audio_url" : "https://storage.example.com/deposition.m4a" ,
"created_at" : "2025-11-04T09:15:30Z"
}
Parameters
Vault Mode
Parameter Type Required Description vault_idstring Yes Vault containing the audio file object_idstring Yes Object ID of the audio file formatstring No Output format: json (default) or text speaker_labelsboolean No Identify different speakers language_codestring No Language code (auto-detected if omitted)
Direct URL Mode
Parameter Type Required Description audio_urlstring Yes URL to audio/video file (max 5GB, 10 hours) webhook_urlstring No URL for completion notification
Shared Options
Parameter Type Default Description speaker_labelsboolean falseIdentify different speakers speakers_expectednumber — Expected number of speakers language_codestring auto Language code (en, es, fr, de, etc.) speech_modelsarray ["universal-3-pro", "universal-2"]Priority-ordered speech models to use punctuateboolean trueAdd punctuation format_textboolean trueFormat numbers, dates, etc. word_boostarray — Boost specific words (e.g., legal terms) auto_highlightsboolean falseDetect key phrases content_safety_labelsboolean falseFlag sensitive content
Get Results (Direct URL Mode)
cURL
CLI
Typescript
Python
Go
curl https://api.case.dev/voice/transcription/JOB_ID \
-H "Authorization: Bearer sk_case_YOUR_API_KEY"
casedev voice:transcription create \
--audio-url "https://storage.example.com/recording.mp3" \
--speaker-labels
const result = await client . voice . transcription . retrieve ( jobId );
if ( result . status === 'completed' ) {
console . log ( result . text ); // Full transcript
// With speaker labels
for ( const utterance of result . utterances ) {
console . log ( ` ${ utterance . speaker } : ${ utterance . text } ` );
}
}
result = client.voice.transcription. retrieve (job_id)
if result.status == 'completed' :
print (result.text) # Full transcript
# With speaker labels
for utterance in result.utterances:
print ( f ' { utterance.speaker } : { utterance.text } ' )
job , _ := client . Voice . Transcription . New ( ctx , casedev . VoiceTranscriptionNewParams {
AudioURL : casedev . F ( "https://storage.example.com/recording.mp3" ),
SpeakerLabels : casedev . F ( true ),
})
fmt . Println ( job . ID )
{
"id" : "474e21cf-fd65-45d4-97fd-87558f7caf9b" ,
"status" : "completed" ,
"audio_duration" : 3847000 ,
"confidence" : 0.94 ,
"text" : "Q: Can you state your name for the record? \n A: My name is Dr. Sarah Johnson..." ,
"utterances" : [
{
"speaker" : "A" ,
"text" : "Can you state your name for the record?" ,
"start" : 120 ,
"end" : 2450
},
{
"speaker" : "B" ,
"text" : "My name is Dr. Sarah Johnson." ,
"start" : 2450 ,
"end" : 4820
}
],
"chapters" : [
{
"headline" : "Witness Introduction" ,
"summary" : "Introduction and witness identification" ,
"start" : 120 ,
"end" : 15000
}
]
}
Status Values
Status Meaning queuedWaiting to start processingTranscribing completedDone, results ready failedError occurred
Processing Times
Audio Length Time 1 minute ~15 seconds 10 minutes ~1-2 minutes 1 hour ~8-10 minutes 3 hours ~20-30 minutes
Examples
Deposition with Speaker Labels (Vault Mode)
casedev voice:transcription create \
--vault-id vault_depositions \
--object-id " $OBJECT_ID " \
--speaker-labels \
--speakers-expected 4 \
--word-boost "plaintiff,defendant,objection,sustained,overruled"
// Upload to vault first
const upload = await client . vault . upload ( 'vault_depositions' , {
filename : 'smith-deposition-2024.mp3' ,
contentType : 'audio/mpeg'
});
const job = await client . voice . transcription . create ({
vault_id : 'vault_depositions' ,
object_id : upload . objectId ,
speaker_labels : true ,
speakers_expected : 4 , // Attorney, witness, court reporter, judge
word_boost : [ 'plaintiff' , 'defendant' , 'objection' , 'sustained' , 'overruled' ]
});
// Poll for completion
let result = await client . voice . transcription . retrieve ( job . id );
while ( result . status === 'processing' ) {
await new Promise ( r => setTimeout ( r , 5000 ));
result = await client . voice . transcription . retrieve ( job . id );
}
// Transcript is now in vault at result.result_object_id
# Upload to vault first
upload = client.vault. upload ( 'vault_depositions' ,
filename = 'smith-deposition-2024.mp3' ,
content_type = 'audio/mpeg'
)
job = client.voice.transcription. create (
vault_id = 'vault_depositions' ,
object_id = upload.object_id,
speaker_labels = True ,
speakers_expected = 4 ,
word_boost = [ 'plaintiff' , 'defendant' , 'objection' , 'sustained' , 'overruled' ]
)
# Poll for completion
result = client.voice.transcription. retrieve (job.id)
while result.status == 'processing' :
import time; time. sleep ( 5 )
result = client.voice.transcription. retrieve (job.id)
# Transcript is now in vault at result.result_object_id
upload , _ := client . Vault . Upload ( ctx , "vault_depositions" , casedev . VaultUploadParams {
Filename : casedev . F ( "smith-deposition-2024.mp3" ),
ContentType : casedev . F ( "audio/mpeg" ),
})
// PUT file to upload.UploadURL via net/http
job , _ := client . Voice . Transcription . New ( ctx , casedev . VoiceTranscriptionNewParams {
VaultID : casedev . F ( "vault_depositions" ),
ObjectID : casedev . F ( upload . ObjectID ),
SpeakerLabels : casedev . F ( true ),
SpeakersExpected : casedev . F ( int64 ( 4 )),
})
// Poll for completion using client.Voice.Transcription.Get(ctx, job.ID)
Court Recording (Direct URL with Webhook)
casedev voice:transcription create \
--audio-url "https://storage.example.com/3-hour-hearing.m4a" \
--speaker-labels \
--webhook-url "https://your-app.com/webhooks/transcription"
const job = await client . voice . transcription . create ({
audio_url : 'https://storage.example.com/3-hour-hearing.m4a' ,
speaker_labels : true ,
webhook_url : 'https://your-app.com/webhooks/transcription'
});
// Results POSTed to your webhook when done
job = client.voice.transcription. create (
audio_url = 'https://storage.example.com/3-hour-hearing.m4a' ,
speaker_labels = True
)
# Poll for results when done
job , _ := client . Voice . Transcription . New ( ctx , casedev . VoiceTranscriptionNewParams {
AudioURL : casedev . F ( "https://storage.example.com/3-hour-hearing.m4a" ),
SpeakerLabels : casedev . F ( true ),
WebhookURL : casedev . F ( "https://your-app.com/webhooks/transcription" ),
})
// Results POSTed to your webhook when done
Audio: MP3, M4A, WAV, FLAC, OGG, OPUS, WebM
Video: MP4, WebM, MOV, AVI, MKV (audio track extracted)
Languages: 100+ including English, Spanish, French, German, Chinese, Japanese
Pricing: $0.01/minute. A 2-hour deposition costs $1.20.