> ## 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.

# Quickstart

> A first request to each model.

## Get an API key

Sign in at [playground.aircaps.com](https://playground.aircaps.com), open **API keys**, and create a key. It is shown once.

```bash theme={null}
export AIRCAPS_API_KEY="aircaps_sk_..."
```

## A5S Async v1: transcribe a recording

**1. Submit audio**

```bash theme={null}
# audio_url: a public or presigned URL (or "file_id" from an upload, below)
# language_code: optional, "en" or the English variant that matches the speakers ("en-US", "en-GB", "en-IN", ...)
curl https://api.aircaps.com/v1/transcripts \
  -H "Authorization: Bearer $AIRCAPS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "a5s-async-v1", "audio_url": "https://example.com/meeting.mp3", "language_code": "en"}'
```

The response is a transcript with `"status": "queued"` or `"processing"` and an `id` like `tr_01k6z...`.

**2. Get the result**

```bash theme={null}
# poll until status is "completed" (or "error"); or pass "webhook_url" when you submit
curl https://api.aircaps.com/v1/transcripts/tr_01k6z... \
  -H "Authorization: Bearer $AIRCAPS_API_KEY"
```

A local file in Python:

```python theme={null}
# pip install requests
# AIRCAPS_API_KEY=aircaps_sk_... python transcribe.py meeting.mp3
import os, sys, time, requests

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

def call(method, path, **kw):
    r = requests.request(method, API + path, headers=HEADERS, timeout=60, **kw)
    if r.status_code >= 400:
        raise SystemExit(r.json()["error"]["message"])
    return r.json()

# 1. Upload straight to storage
upload = call("POST", "/files/upload-url")
with open(sys.argv[1], "rb") as f:
    requests.put(upload["upload_url"], data=f, timeout=600).raise_for_status()

# 2. Transcribe
job = call("POST", "/transcripts", json={
    "model": "a5s-async-v1",
    "file_id": upload["id"],
    "language_code": "en",                  # optional
    # "webhook_url": "https://...",         # optional: get notified instead of polling
    # "speaker_identification": True,       # optional: names from enrolled voices (AirCaps Speaker ID-v1)
})

# 3. Wait for the result
while job["status"] in ("queued", "processing"):
    time.sleep(3)
    job = call("GET", f"/transcripts/{job['id']}")

if job["status"] == "error":
    raise SystemExit(job["error"]["message"])
for u in job["utterances"]:
    print(f"[{u['start']:7.1f}s] {u['speaker']}: {u['text']}")
```

## A5S Small V2 Streaming: live captions

```python theme={null}
# pip install websockets==15.0.1
# AIRCAPS_API_KEY=aircaps_sk_... python stream.py audio.wav   (mono 16 kHz 16-bit PCM WAV)
import asyncio, json, os, sys, wave
import websockets

async def main(path):
    headers = {"Authorization": f"Bearer {os.environ['AIRCAPS_API_KEY']}"}
    async with websockets.connect("wss://api.aircaps.com/v1/realtime", additional_headers=headers) as ws:
        await ws.send(json.dumps({
            "type": "start",
            "providers": ["a5sv2"],
            "encoding": "pcm_s16le", "sample_rate": 16000, "channels": 1,   # the only audio format
            "language": "en",
            "diarization": True,                                            # optional: live speaker labels
        }))
        while (event := json.loads(await ws.recv()))["type"] != "ready":  # wait for ready before sending audio
            if event["type"] == "error":
                raise SystemExit(event["message"])

        async def send_audio():
            with wave.open(path, "rb") as audio:
                while chunk := audio.readframes(320):                      # 20 ms per frame, in real time
                    await ws.send(chunk)
                    await asyncio.sleep(0.02)
            await ws.send(json.dumps({"type": "finish"}))                  # final transcript, then "finished"

        sender = asyncio.create_task(send_audio())
        async for message in ws:                                           # until the server closes the session
            event = json.loads(message)
            if event["type"] == "transcript" and event["is_final"]:
                print(event["text"])                                       # the whole transcript so far
        await sender

asyncio.run(main(sys.argv[1]))
```

## AirCaps Diarization-v1: who spoke when

```bash theme={null}
# Start a diarization (audio_url or file_id; optional: webhook_url, metadata)
curl https://api.aircaps.com/v1/diarizations \
  -H "Authorization: Bearer $AIRCAPS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "aircaps-diarization-v1", "audio_url": "https://example.com/meeting.mp3"}'

# Poll until status is "completed": speakers, and segments of {speaker, start, end}
curl https://api.aircaps.com/v1/diarizations/dia_01k72... \
  -H "Authorization: Bearer $AIRCAPS_API_KEY"

# The same segments as RTTM
curl https://api.aircaps.com/v1/diarizations/dia_01k72.../rttm \
  -H "Authorization: Bearer $AIRCAPS_API_KEY"
```

## AirCaps Speaker ID-v1: recognize enrolled voices

```bash theme={null}
# 1. Create a speaker (name and metadata are optional)
curl https://api.aircaps.com/v1/speakers \
  -H "Authorization: Bearer $AIRCAPS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Ana García"}'

# 2. Enroll a clip of that person speaking alone: raw audio bytes as the body, 1 s to 2 min
curl https://api.aircaps.com/v1/speakers/spk_01k73.../enrollments \
  -H "Authorization: Bearer $AIRCAPS_API_KEY" \
  -H "Content-Type: audio/wav" \
  --data-binary @ana.wav

# 3. Identify a clip: a score for every enrolled speaker, best first (optional: speaker_ids, top_k)
curl "https://api.aircaps.com/v1/speakers/identify?top_k=3" \
  -H "Authorization: Bearer $AIRCAPS_API_KEY" \
  -H "Content-Type: audio/wav" \
  --data-binary @clip.wav
```

To name the speakers of a transcript or a live stream instead, add `"speaker_identification": true` to the request ([transcripts](https://aircaps.ai/docs/guides/async-transcription.md#speaker-names), [live streams](https://aircaps.ai/docs/guides/streaming.md#speaker-names)).

> [!NOTE]
>
> **Access:** AirCaps Diarization-v1 and AirCaps Speaker ID-v1 are enabled per account; without access, requests return `403 model_access_denied`. [Talk to sales](https://aircaps.ai/contact) to get access.
>
> **Language:** A5S Async v1 and A5S Small V2 Streaming transcribe English only today: `language_code` (batch) takes `en` or a regional English code such as `en-US`, `en-GB` or `en-IN`, and `language` (streaming) takes `en`. Multilingual support is planned and will be available soon.

Next: [batch transcription](https://aircaps.ai/docs/guides/async-transcription.md), [live streaming](https://aircaps.ai/docs/guides/streaming.md), [speaker diarization](https://aircaps.ai/docs/guides/diarization.md) or [speaker identification](https://aircaps.ai/docs/guides/speaker-id.md).


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