Transcriptions
Transcribe audio files to text using the Sansa API
Converts an audio file to text. Compatible with the OpenAI audio.transcriptions SDK client. Pass sansa-auto or OpenAI aliases for Sansa's default transcription model, or any audio-capable catalog model id for a direct call.
POST /v1/audio/transcriptions
The request body must be multipart/form-data. See the code panel for examples in Python, TypeScript, and curl.
Form Parameters
file
Required. The audio file to transcribe. Must be multipart/form-data.
Supported formats: flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav, webm.
Maximum file size: 25 MB.
model
Optional. Default: "gpt-4o-transcribe" (OpenAI SDK compatibility).
| Value | Behavior |
|---|---|
sansa-auto, whisper-1, gpt-4o-transcribe, gpt-4o-mini-transcribe, or omitted | Routes to Sansa's default transcription model (google/gemini-2.5-flash-lite) |
| Any other catalog model id | Uses that model directly; must support audio input (audio in input_modalities) |
Invalid or unknown model ids return 400 with invalid_model. Models without audio support return 400 with a descriptive invalid_model message.
Pass "whisper-1" or "gpt-4o-transcribe" when using the OpenAI SDK without changes.
language
Optional. ISO-639-1 language code (e.g., "en", "fr", "de"). Providing the language improves accuracy and speed. If omitted, the model detects the language automatically.
prompt
Optional. A text string to guide the model's style or provide context for the audio. Useful for supplying proper nouns, acronyms, or domain-specific vocabulary that the model might otherwise transcribe incorrectly.
temperature
Default: 0.0. Sampling temperature between 0.0 and 1.0. Lower values produce more deterministic output.
response_format
Default: "json". Controls the output format.
| Value | Description |
|---|---|
"json" | Returns {"text": "..."} |
"text" | Returns the transcription as a plain string |
Only "json" and "text" are supported. Other values return 400 with code unsupported_response_format.
call_name
Optional. Legacy top-level dashboard label for the request (max 64 characters, non-whitespace). Prefer sansa or metadata instead; see Request labels below.
sansa
Optional. A JSON object string in the multipart form. Preferred container for Sansa-specific fields such as call_name and end_user_id. Example form value:
{"call_name": "voicemail-transcribe", "end_user_id": "user-42"}metadata
Optional. A JSON object string in the multipart form. Fallback container for the same keys when you cannot send a sansa object. Keys other than call_name and end_user_id are accepted for OpenAI SDK compatibility but are not stored.
Request labels
Org, project, and environment are derived from your API key, not from the request. Optional labels help you filter and organize activity in the dashboard.
Because transcriptions use multipart/form-data, sansa and metadata are sent as JSON-encoded form field strings (not nested objects in a JSON body).
| Field | Precedence | Stored as | Purpose |
|---|---|---|---|
call_name | sansa.call_name ?? metadata.call_name ?? top-level call_name | callName | Request label in the dashboard (max 64 chars) |
end_user_id | sansa.end_user_id ?? metadata.end_user_id | endUserExternalId | Customer end-user label in activity (max 512 chars) |
Precedence is per field: when a key is present in sansa, that value wins; otherwise metadata is used. Top-level call_name applies only when the key is absent from both objects.
Invalid values return 400 with invalid_call_name or invalid_end_user_id. Malformed sansa or metadata JSON returns 400 with invalid_request.
Reserved keys under sansa (memory, eval, policy) may be sent today; they are parsed and ignored until those features ship.
curl -X POST https://api.sansaml.com/v1/audio/transcriptions \
-H "Authorization: Bearer $SANSA_API_KEY" \
-F "file=@audio.mp3" \
-F 'sansa={"call_name":"voicemail-transcribe","end_user_id":"user-42"}'Returns
JSON (default)
{
"text": "Hello, world. This is a transcription of the audio."
}Text
A plain string with the transcription. The Content-Type header will be text/plain.
Errors
| HTTP Status | Code | When |
|---|---|---|
400 | invalid_request | File missing, filename missing, or file is empty |
400 | invalid_file_format | File extension not in supported formats |
400 | file_too_large | File exceeds 25 MB |
400 | invalid_model | Unknown model id, or model does not support audio input |
403 | endpoint_not_allowed | API key endpoint allowlist excludes audio.transcriptions |
403 | model_not_allowed | Resolved model is outside the key's model allowlist |
400 | unsupported_response_format | response_format is not "json" or "text" |
400 | invalid_call_name | call_name is empty, whitespace-only, or exceeds 64 characters |
400 | invalid_end_user_id | end_user_id is empty, whitespace-only, or exceeds 512 characters |
401 | unauthorized | Invalid or missing API key |
402 | insufficient_credits | Account balance is zero or negative |
429 | rate_limit_exceeded | Too many requests |
500 | internal_error | Unexpected server error |
Billing
- Cost is estimated before the request and reserved from your balance.
- After the response completes, cost is recalculated using actual token usage and the difference is refunded or deducted.
- Failed requests are not charged.
Audio in chat completions
For conversational use cases — asking the model questions about audio content, or sending audio as part of a multi-turn conversation — use input_audio content parts in /v1/chat/completions instead. See the Completions docs for the ContentPart interface.