> ## Documentation Index
> Fetch the complete documentation index at: https://impossibl.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Audio and video input

> Send audio and video alongside text on Chat Completions, the Responses API, and the Gemini-native endpoint. Output stays text; audio tokens can carry their own rate.

The gateway accepts **audio and video input** for models that declare the
modality — check `input_modalities` in [`GET /v1/models`](/docs/api-reference).
Sending audio or video to any other model fails fast with
`400 invalid_request_error` before anything is billed. Output is still text
only.

Today that means the **Gemini family** (`google/gemini-*`): every catalog
Gemini model accepts image, audio, and video input.

## Audio

### Chat Completions

Use OpenAI-style `input_audio` parts: base64 data plus a format token
(`wav` or `mp3`; `aiff`, `aac`, `ogg` and `flac` also pass through):

```bash theme={null}
curl https://api.impossibl.com/v1/chat/completions \
  -H "Authorization: Bearer imp-rt-..." \
  -H 'content-type: application/json' \
  -d '{
    "model": "google/gemini-2.5-flash",
    "messages": [{
      "role": "user",
      "content": [
        { "type": "text", "text": "Transcribe this recording." },
        { "type": "input_audio", "input_audio": { "data": "UklGRiQ...", "format": "wav" } }
      ]
    }]
  }'
```

### Responses API

The same `input_audio` shape, paired with `input_text`:

```bash theme={null}
curl https://api.impossibl.com/v1/responses \
  -H "Authorization: Bearer imp-rt-..." \
  -H 'content-type: application/json' \
  -d '{
    "model": "google/gemini-2.5-flash",
    "input": [{
      "role": "user",
      "content": [
        { "type": "input_text", "text": "Summarize this recording." },
        { "type": "input_audio", "input_audio": { "data": "UklGRiQ...", "format": "wav" } }
      ]
    }]
  }'
```

## Video

### Chat Completions

Use `video_url` parts (the de-facto extension Qwen and Zhipu clients already
send). The `url` is a `data:` URI or an http(s) URL. **YouTube URLs** pass
straight through to Gemini; any other video URL is fetched by the gateway and
sent inline, so it must fit Gemini's \~20MB inline request limit:

```bash theme={null}
curl https://api.impossibl.com/v1/chat/completions \
  -H "Authorization: Bearer imp-rt-..." \
  -H 'content-type: application/json' \
  -d '{
    "model": "google/gemini-2.5-flash",
    "messages": [{
      "role": "user",
      "content": [
        { "type": "text", "text": "What happens in this video?" },
        { "type": "video_url", "video_url": { "url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" } }
      ]
    }]
  }'
```

A `data:` URI carries the video inline: `data:video/mp4;base64,...`.

### Gemini-native endpoint

`/v1beta/models/{model}:generateContent` accepts Google's own shapes:
`inlineData` for base64 audio/video (routed by `mimeType`) and `fileData` for
video URLs:

```bash theme={null}
curl "https://api.impossibl.com/v1beta/models/google%2Fgemini-2.5-flash:generateContent" \
  -H "Authorization: Bearer imp-rt-..." \
  -H 'content-type: application/json' \
  -d '{
    "contents": [{
      "role": "user",
      "parts": [
        { "text": "Summarize this video." },
        { "fileData": { "mimeType": "video/mp4", "fileUri": "https://www.youtube.com/watch?v=dQw4w9WgXcQ" } }
      ]
    }]
  }'
```

## Billing

Audio and video are tokenized by the provider (Gemini: \~32 tokens per second
of audio, \~300 per second of video) and billed as input tokens. Some models
price audio input above the text rate — `pricing.audio_input_per_mtok_usd` in
`GET /v1/models` shows the rate where one applies (e.g.
`google/gemini-2.5-flash` bills audio at $1.00/1M vs $0.30 text). Video frames
bill at the model's input rate, but a video's audio track is tokenized
separately and bills at the audio rate where the model declares one.
