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

# Speaker diarization

> Find who spoke when in a recording with AirCaps Diarization-v1.

AirCaps Diarization-v1 answers **who spoke when**: it labels every stretch of speech in a recording with a speaker, including overlapping speech, and returns no transcript. Use it to segment meetings, interviews and calls by speaker, to count speakers, or to attach speakers to a transcript you already have.

> [!NOTE]
>
> AirCaps Diarization-v1 is enabled per account. If `GET /v1/account` shows `"enabled": false` for `aircaps-diarization-v1`, requests return `403 model_access_denied`. To get access, [talk to sales](https://aircaps.ai/contact).

## 1. Provide the audio

The same sources as [batch transcription](https://aircaps.ai/docs/guides/async-transcription.md#1-provide-the-audio): an `audio_url`, or a `file_id` from an [upload URL](https://aircaps.ai/docs/api-reference/upload-url.md) or a [direct upload](https://aircaps.ai/docs/api-reference/upload-file.md). Any audio format ffmpeg can read works; channels are mixed down. Files are 0.1 s to 6 hours long.

## 2. Create the diarization

```bash theme={null}
curl https://api.aircaps.com/v1/diarizations \
  -H "Authorization: Bearer $AIRCAPS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: meeting-2026-10-08" \
  -d '{
        "model": "aircaps-diarization-v1",
        "audio_url": "https://example.com/meeting.mp3",
        "webhook_url": "https://example.com/hooks/aircaps",
        "metadata": {"meeting_id": 42}
      }'
```

The response is a [diarization](https://aircaps.ai/docs/api-reference/objects/diarization.md) with `status: "queued"` or `"processing"`. `model` is optional. `metadata` (up to 16 KB) is echoed back on the diarization and in webhooks.

> [!TIP]
>
> There is no `language_code`: diarization works from the voices, not the words.

## 3. Get the result

Wait for a [webhook](https://aircaps.ai/docs/guides/webhooks.md) (`diarization.completed` or `diarization.failed`) or poll [`GET /v1/diarizations/{id}`](https://aircaps.ai/docs/api-reference/get-diarization) every few seconds.

| status | Meaning |
| - | - |
| `queued` | Waiting for one of your account's processing slots |
| `processing` | Being diarized |
| `completed` | Done; result fields are present |
| `error` | Failed; see `error` |

## The result

```json theme={null}
{
  "id": "dia_01k72p0x9h6t3b8r1n4m7q2w5e",
  "object": "diarization",
  "status": "completed",
  "model": "aircaps-diarization-v1",
  "audio_duration": 1834.112,
  "num_speakers": 3,
  "speakers": [
    {"id": "speaker_0", "speaking_time": 702.31},
    {"id": "speaker_1", "speaking_time": 611.08},
    {"id": "speaker_2", "speaking_time": 240.6}
  ],
  "segments": [
    {"speaker": "speaker_0", "start": 0.48, "end": 6.12},
    {"speaker": "speaker_1", "start": 5.9, "end": 9.33},
    {"speaker": "speaker_0", "start": 9.71, "end": 14.02}
  ],
  "speech_duration": 1498.27,
  "overlap_duration": 61.44
}
```

* `segments` are in time order. **Overlapping speech appears as overlapping segments of different speakers** (above, speaker 0 and speaker 1 both talk from 5.9 s to 6.12 s).
* Times are seconds from the start of the audio, with millisecond precision.
* Speakers are numbered in order of first speech and are consistent within one diarization only. The model finds the number of speakers itself.
* `speech_duration` is the time anyone speaks; `overlap_duration` is the time two or more people speak at once.
* Audio with no speech completes with `num_speakers: 0` and empty `speakers` and `segments`.

### RTTM

[`GET /v1/diarizations/{id}/rttm`](https://aircaps.ai/docs/api-reference/diarization-rttm) returns the same segments as an RTTM file, the format diarization scoring tools read:

```text theme={null}
SPEAKER dia_01k72p0x9h6t3b8r1n4m7q2w5e 1 0.480 5.640 <NA> <NA> speaker_0 <NA> <NA>
SPEAKER dia_01k72p0x9h6t3b8r1n4m7q2w5e 1 5.900 3.430 <NA> <NA> speaker_1 <NA> <NA>
```

## Python example

```python theme={null}
import os, time, requests

API = "https://api.aircaps.com/v1"
H = {"Authorization": f"Bearer {os.environ['AIRCAPS_API_KEY']}"}

with open("meeting.wav", "rb") as f:
    file_id = requests.post(f"{API}/files", headers=H, data=f).json()["id"]

job = requests.post(f"{API}/diarizations", headers=H,
                    json={"model": "aircaps-diarization-v1", "file_id": file_id}).json()
while job["status"] in ("queued", "processing"):
    time.sleep(5)
    job = requests.get(f"{API}/diarizations/{job['id']}", headers=H).json()

for s in job.get("segments", []):
    print(f"{s['start']:8.2f} {s['end']:8.2f}  {s['speaker']}")
```

## Limits and usage

* Audio is billed by duration and counts toward your account's [usage limit](https://aircaps.ai/docs/limits.md), shared by all models. Failed jobs don't count.
* Diarizations share your account's asynchronous job limits (concurrent jobs, queue, requests per minute) with transcripts.
* Files up to 6 hours. Longer files fail with `audio_too_long`.

## Delete

[`DELETE /v1/diarizations/{id}`](https://aircaps.ai/docs/api-reference/delete-diarization) cancels a running job or deletes a finished diarization, its stored result and the uploaded file it used. Diarizations are otherwise deleted after 30 days.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.