Multimodal
Audio inputs
Send recorded audio to audio-capable chat models with the input_audio content part.
Audio-capable chat models can answer questions about a call, summarize a voice memo or follow spoken instructions. Add an input_audio content part to a user message with the audio as base64 and its format. The examples use openai/gpt-6-luna; replace it with a model that has an endpoint whose input_modalities include audio. If you only need the spoken words, use transcription.
Send an audio file
{ "model": "openai/gpt-6-luna", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "What does the caller ask for, and what tone do they use?" }, { "type": "input_audio", "input_audio": { "data": "UklGRiQAAABXQVZFZm10...", "format": "wav" } } ] } ]}Read the file, encode it with standard base64 and pick the format that matches its container:
import base64import osfrom pathlib import Pathfrom openai import OpenAIFORMATS = {".wav": "wav", ".mp3": "mp3", ".flac": "flac", ".m4a": "m4a", ".ogg": "ogg", ".webm": "webm", ".aac": "aac", ".aiff": "aiff", ".aif": "aiff"}def audio_part(path: str) -> dict: file = Path(path) data = base64.b64encode(file.read_bytes()).decode("ascii") return {"type": "input_audio", "input_audio": {"data": data, "format": FORMATS[file.suffix.lower()]}}client = OpenAI(base_url="https://api.numes.ai/api/v1", api_key=os.environ["NUMES_API_KEY"])completion = client.chat.completions.create( model="openai/gpt-6-luna", messages=[ { "role": "user", "content": [ {"type": "text", "text": "Summarize this voice memo as a to-do list."}, audio_part("memo.mp3"), ], } ],)print(completion.choices[0].message.content)data is the bare base64 string: no data:audio/...;base64, prefix, and no URL. Audio is always inline, so it counts toward the 10 MiB chat body limit after base64 adds about a third. Keep the audio in one request under about 7.5 MiB, compress it (for example mono Ogg or low-bitrate MP3), or use transcription for long recordings.
The input_audio part
Content part
type"input_audio"RequiredIdentifies an audio part.
input_audioobjectRequiredThe audio clip.
Show child attributesHide child attributes
datastringRequiredStandard base64 of the complete audio file. Must not be empty.
formatstringRequiredwav,mp3,flac,m4a,ogg,webm,aac,aiff,pcm16orpcm24.
You can attach several clips to one message; they reach the model in the order you list them.
Supported formats
The format you declare must match the file's bytes. A mismatch, such as mp3 for an M4A file, is rejected.
format | Media type | Notes |
|---|---|---|
wav | audio/wav | RIFF WAVE |
mp3 | audio/mpeg | With or without an ID3 tag |
flac | audio/flac | |
m4a | audio/mp4 | MP4 audio container |
ogg | audio/ogg | Opus or Vorbis |
webm | audio/webm | Some browser recordings are rejected; see below |
aac | audio/aac | ADTS stream |
aiff | audio/aiff | AIFF or AIFF-C |
pcm16 | audio/pcm | Raw PCM, 24 kHz, mono, 16-bit samples |
pcm24 | audio/pcm | Raw PCM, 24 kHz, mono, 24-bit samples |
Raw PCM has no header, so it's read as 24 kHz mono, and its length must be a whole number of samples. Resample other PCM to 24 kHz first, or wrap it in a WAV header.
Every clip must have a measurable duration, and all audio in one request may last at most 1 hour. Audio that can't be parsed, is truncated or exceeds the limit is rejected with 400. Some browser recordings, such as WebM files from MediaRecorder, can't be measured; re-mux them or send Ogg or WAV.
Route to audio-capable endpoints
Routing considers only endpoints whose input_modalities include audio. Check a model's endpoints first:
curl "https://api.numes.ai/api/v1/models/author/audio-model/endpoints" \ -H "Authorization: Bearer $NUMES_API_KEY"Billing
Endpoints price input audio either per second, reported as input_audio_seconds in usage, or as prompt tokens. Text tokens and any per-request price apply as usual. pricing.audio in GET /models shows the lowest audio rate of the model's representative endpoint. See Usage accounting.
Chat audio or transcription
Chat with input_audio | Transcription | |
|---|---|---|
| Result | A model's answer about the audio | The spoken words as text |
| Upload | Base64 inside the JSON body | Multipart upload or base64 JSON |
| Practical size | About 7.5 MiB of audio per request | Up to 8 MiB per file |
| Text instructions | Yes | No |
To produce speech, use text to speech.
Troubleshooting
Audio problems return 400 invalid_request. On chat completions the message names the failing part, such as messages[0].content[1].input_audio.
| Symptom | Cause and fix |
|---|---|
| 400 with a correct-looking file | format doesn't match the bytes, for example an .mp3 file that is really M4A. |
400 with a data: prefix or a URL in data | Send bare base64 of the file itself. |
| 400 for a browser WebM recording | Re-mux it or send Ogg or WAV. |
| 400 for PCM | The data length isn't a whole number of 16-bit or 24-bit samples. |
| 400 for long audio | A clip exceeds 8 MiB or all audio exceeds 1 hour. Split it or use transcription. |
413 payload_too_large | The base64 audio pushed the body over 10 MiB. |
503 provider_unavailable | No endpoint for the model accepts audio input. |