curl --request POST \
--url https://nano-gpt.com/api/transcribe \
--header 'Content-Type: multipart/form-data' \
--header 'x-api-key: <api-key>' \
--form audio='@example-file' \
--form 'audioUrl=<string>' \
--form model=Whisper-Large-V3 \
--form language=en \
--form 'actualDuration=<string>' \
--form diarize=false \
--form tagAudioEvents=falseimport requests
url = "https://nano-gpt.com/api/transcribe"
files = { "audio": ("example-file", open("example-file", "rb")) }
payload = {
"audioUrl": "<string>",
"model": "Whisper-Large-V3",
"language": "en",
"actualDuration": "<string>",
"diarize": "false",
"tagAudioEvents": "false"
}
headers = {"x-api-key": "<api-key>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('audio', '<string>');
form.append('audioUrl', '<string>');
form.append('model', 'Whisper-Large-V3');
form.append('language', 'en');
form.append('actualDuration', '<string>');
form.append('diarize', 'false');
form.append('tagAudioEvents', 'false');
const options = {method: 'POST', headers: {'x-api-key': '<api-key>'}};
options.body = form;
fetch('https://nano-gpt.com/api/transcribe', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://nano-gpt.com/api/transcribe",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audio\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audioUrl\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nWhisper-Large-V3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"actualDuration\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"diarize\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"tagAudioEvents\"\r\n\r\nfalse\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Content-Type: multipart/form-data",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://nano-gpt.com/api/transcribe"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audio\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audioUrl\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nWhisper-Large-V3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"actualDuration\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"diarize\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"tagAudioEvents\"\r\n\r\nfalse\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://nano-gpt.com/api/transcribe")
.header("x-api-key", "<api-key>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audio\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audioUrl\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nWhisper-Large-V3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"actualDuration\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"diarize\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"tagAudioEvents\"\r\n\r\nfalse\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://nano-gpt.com/api/transcribe")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audio\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audioUrl\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nWhisper-Large-V3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"actualDuration\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"diarize\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"tagAudioEvents\"\r\n\r\nfalse\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"transcription": "Hello, this is a test transcription.",
"metadata": {
"cost": 123,
"currency": "USD",
"model": "<string>",
"fileName": "<string>",
"fileSize": 123,
"chargedDuration": 123,
"actualDuration": 123,
"language": "<string>"
}
}{
"runId": "abc123def456",
"status": "pending",
"model": "<string>",
"cost": 123,
"paymentSource": "<string>",
"isApiRequest": true,
"fileName": "<string>",
"fileSize": 123,
"chargedDuration": 123,
"diarize": true
}{
"error": 123,
"message": "<string>"
}{
"error": 123,
"message": "<string>"
}{
"error": 123,
"message": "<string>"
}{
"error": 123,
"message": "<string>"
}Speech-to-Text Transcription
Transcribe audio (and supported video formats) into text using speech recognition models. Supports multiple languages, diarization (model-dependent), and various formats. Most models return synchronous results; some models (for example Elevenlabs-STT and voice cloning workflows) return asynchronous job IDs.
curl --request POST \
--url https://nano-gpt.com/api/transcribe \
--header 'Content-Type: multipart/form-data' \
--header 'x-api-key: <api-key>' \
--form audio='@example-file' \
--form 'audioUrl=<string>' \
--form model=Whisper-Large-V3 \
--form language=en \
--form 'actualDuration=<string>' \
--form diarize=false \
--form tagAudioEvents=falseimport requests
url = "https://nano-gpt.com/api/transcribe"
files = { "audio": ("example-file", open("example-file", "rb")) }
payload = {
"audioUrl": "<string>",
"model": "Whisper-Large-V3",
"language": "en",
"actualDuration": "<string>",
"diarize": "false",
"tagAudioEvents": "false"
}
headers = {"x-api-key": "<api-key>"}
response = requests.post(url, data=payload, files=files, headers=headers)
print(response.text)const form = new FormData();
form.append('audio', '<string>');
form.append('audioUrl', '<string>');
form.append('model', 'Whisper-Large-V3');
form.append('language', 'en');
form.append('actualDuration', '<string>');
form.append('diarize', 'false');
form.append('tagAudioEvents', 'false');
const options = {method: 'POST', headers: {'x-api-key': '<api-key>'}};
options.body = form;
fetch('https://nano-gpt.com/api/transcribe', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://nano-gpt.com/api/transcribe",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audio\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audioUrl\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nWhisper-Large-V3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"actualDuration\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"diarize\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"tagAudioEvents\"\r\n\r\nfalse\r\n-----011000010111000001101001--",
CURLOPT_HTTPHEADER => [
"Content-Type: multipart/form-data",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://nano-gpt.com/api/transcribe"
payload := strings.NewReader("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audio\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audioUrl\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nWhisper-Large-V3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"actualDuration\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"diarize\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"tagAudioEvents\"\r\n\r\nfalse\r\n-----011000010111000001101001--")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://nano-gpt.com/api/transcribe")
.header("x-api-key", "<api-key>")
.body("-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audio\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audioUrl\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nWhisper-Large-V3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"actualDuration\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"diarize\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"tagAudioEvents\"\r\n\r\nfalse\r\n-----011000010111000001101001--")
.asString();require 'uri'
require 'net/http'
url = URI("https://nano-gpt.com/api/transcribe")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request.body = "-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audio\"; filename=\"example-file\"\r\nContent-Type: application/octet-stream\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"audioUrl\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nWhisper-Large-V3\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"language\"\r\n\r\nen\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"actualDuration\"\r\n\r\n<string>\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"diarize\"\r\n\r\nfalse\r\n-----011000010111000001101001\r\nContent-Disposition: form-data; name=\"tagAudioEvents\"\r\n\r\nfalse\r\n-----011000010111000001101001--"
response = http.request(request)
puts response.read_body{
"transcription": "Hello, this is a test transcription.",
"metadata": {
"cost": 123,
"currency": "USD",
"model": "<string>",
"fileName": "<string>",
"fileSize": 123,
"chargedDuration": 123,
"actualDuration": 123,
"language": "<string>"
}
}{
"runId": "abc123def456",
"status": "pending",
"model": "<string>",
"cost": 123,
"paymentSource": "<string>",
"isApiRequest": true,
"fileName": "<string>",
"fileSize": 123,
"chargedDuration": 123,
"diarize": true
}{
"error": 123,
"message": "<string>"
}{
"error": 123,
"message": "<string>"
}{
"error": 123,
"message": "<string>"
}{
"error": 123,
"message": "<string>"
}Overview
The Speech-to-Text transcription endpoint converts audio files into text using state-of-the-art speech recognition models. Supports multiple languages, speaker diarization, and various audio formats. Looking for a drop-in OpenAI-compatible STT endpoint? UsePOST /api/v1/audio/transcriptions. See api-reference/endpoint/audio-transcriptions.mdx.
Supported Models
- Whisper-Large-V3: High-accuracy transcription (~$0.0005/min) - Synchronous
- Wizper: Fast and efficient transcription ($0.01/min) - Synchronous
- Elevenlabs-STT: Premium transcription with diarization ($0.03/min) - Asynchronous
- gpt-4o-mini-transcribe: Efficient OpenAI transcription ($0.003/min) - Synchronous
- gpt-4o-mini-transcribe-2025-03-20: Snapshot ($0.003/min) - Synchronous
- gpt-4o-mini-transcribe-2025-12-15: Snapshot ($0.003/min) - Synchronous
- gpt-4o-mini-transcribe-latest: Alias ($0.003/min) - Synchronous
- openai-whisper-with-video: Video-to-text transcription ($0.06/min) - Synchronous
- qwen-voice-clone: Voice cloning ($0.25/run) - Asynchronous
- minimax-voice-clone: Voice cloning ($1.00/run) - Asynchronous
Upload Methods
Direct File Upload (≤3MB)
import requests
def transcribe_file(file_path):
headers = {"x-api-key": "YOUR_API_KEY"}
with open(file_path, 'rb') as audio_file:
files = {'audio': ('audio.mp3', audio_file, 'audio/mpeg')}
data = {
'model': 'Whisper-Large-V3',
'language': 'en'
}
response = requests.post(
"https://nano-gpt.com/api/transcribe",
headers=headers,
files=files,
data=data
)
return response.json()
result = transcribe_file("meeting.mp3")
print(result['transcription'])
const formData = new FormData();
formData.append('audio', audioFile);
formData.append('model', 'Whisper-Large-V3');
formData.append('language', 'auto');
const response = await fetch('https://nano-gpt.com/api/transcribe', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY'
},
body: formData
});
const result = await response.json();
console.log(result.transcription);
curl -X POST https://nano-gpt.com/api/transcribe \
-H "x-api-key: YOUR_API_KEY" \
-F "audio=@meeting.mp3" \
-F "model=Whisper-Large-V3" \
-F "language=en"
URL Upload (≤500MB)
import requests
def transcribe_url(audio_url):
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"audioUrl": audio_url,
"model": "Wizper",
"language": "auto"
}
response = requests.post(
"https://nano-gpt.com/api/transcribe",
headers=headers,
json=data
)
return response.json()
result = transcribe_url("https://example.com/audio.mp3")
print(result['transcription'])
const response = await fetch('https://nano-gpt.com/api/transcribe', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
audioUrl: 'https://example.com/audio.mp3',
model: 'Wizper',
language: 'auto'
})
});
const result = await response.json();
console.log(result.transcription);
curl -X POST https://nano-gpt.com/api/transcribe \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"audioUrl": "https://example.com/audio.mp3",
"model": "Wizper",
"language": "auto"
}'
Advanced Features - Speaker Diarization
Use Elevenlabs-STT for speaker identification (asynchronous processing):import requests
import time
def transcribe_with_speakers(audio_url):
headers = {
"x-api-key": "YOUR_API_KEY",
"Content-Type": "application/json"
}
# Submit transcription job
data = {
"audioUrl": audio_url,
"model": "Elevenlabs-STT",
"diarize": True,
"tagAudioEvents": True
}
response = requests.post(
"https://nano-gpt.com/api/transcribe",
headers=headers,
json=data
)
if response.status_code == 202:
job_data = response.json()
# Poll for results
status_data = {
"runId": job_data['runId'],
"cost": job_data.get('cost'),
"paymentSource": job_data.get('paymentSource'),
"isApiRequest": True
}
while True:
status_response = requests.post(
"https://nano-gpt.com/api/transcribe/status",
headers=headers,
json=status_data
)
result = status_response.json()
if result.get('status') == 'completed':
return result
elif result.get('status') == 'failed':
raise Exception(f"Transcription failed: {result.get('error')}")
time.sleep(5)
result = transcribe_with_speakers("https://example.com/meeting.mp3")
# Access speaker segments
for segment in result['diarization']['segments']:
print(f"{segment['speaker']}: {segment['text']}")
Language Support
Supports 97+ languages with auto-detection:# Common language codes
languages = {
"auto": "Auto-detect",
"en": "English",
"es": "Spanish",
"fr": "French",
"de": "German",
"zh": "Chinese",
"ja": "Japanese",
"ar": "Arabic"
}
Response Examples
Synchronous Response (most models)
{
"transcription": "Hello, this is a test transcription.",
"metadata": {
"fileName": "audio.mp3",
"fileSize": 1234567,
"chargedDuration": 2.5,
"actualDuration": 2.5,
"language": "en",
"cost": 0.0012,
"currency": "USD",
"model": "Whisper-Large-V3"
}
}
Asynchronous Response (Elevenlabs-STT and voice cloning)
Initial response (202):{
"runId": "abc123def456",
"status": "pending",
"model": "Elevenlabs-STT",
"cost": 0.075,
"paymentSource": "USD"
}
{
"status": "completed",
"transcription": "Speaker 1: Hello everyone. Speaker 2: Hi there!",
"metadata": { ... },
"diarization": {
"segments": [
{
"speaker": "Speaker 1",
"text": "Hello everyone",
"start": 0.5,
"end": 1.5
}
]
},
"words": [
{
"text": "Hello",
"start": 0.5,
"end": 0.9,
"type": "word",
"speaker_id": "speaker_0"
}
]
}
Authorizations
Body
Audio transcription parameters. Use multipart/form-data for file uploads or application/json for URL-based requests.
Direct file upload (max 3MB). Supported formats: MP3, WAV, M4A, OGG, AAC
URL to audio file (alternative to direct upload, supports up to 500MB)
The STT model to use for transcription
Whisper-Large-V3, Wizper, Elevenlabs-STT, gpt-4o-mini-transcribe, gpt-4o-mini-transcribe-2025-03-20, gpt-4o-mini-transcribe-2025-12-15, gpt-4o-mini-transcribe-latest, openai-whisper-with-video, qwen-voice-clone, minimax-voice-clone Language code for transcription (ISO 639-1 or ISO 639-3). Use 'auto' for auto-detection
"en"
Actual audio duration in minutes for accurate billing
Enable speaker diarization (Elevenlabs-STT only)
true, false Tag non-speech audio events like [laughter], [applause] (Elevenlabs-STT only)
true, false