# Diarization

> Identify and label the speakers in multi-speaker Arabic audio, then get each speaker segment aligned with transcribed text and timestamps — who said what in meetings, interviews, podcasts and conversations.

## Endpoint

`POST /api/v1/audio/diarization/transcribe`

Authenticate with your API key in the `x-api-key` header. See [Authentication](/authentication).

| Header | Value |
| --- | --- |
| `x-api-key` | YOUR\_MUNSIT\_API\_KEY |

## Request

Send the body as `multipart/form-data`. How it works: you upload a multi-speaker file, Munsit identifies speaker turns and assigns speaker labels, and you receive transcription, diarization segments, and merged speaker-labeled text with timing.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `file` | file | **Yes** | Audio file in a supported format — see [what you can send](/speech-to-text/get-started#send). |
| `model` | string | No | ASR model to use: `munsit` (default) or `munsit-en-ar` (mixed Arabic-English with code-switching). |

> Transcribe-only options. hotwords, language and return_confidence apply to POST /audio/transcribe only.
> Only need to know who said what? Add diarize=true to POST /audio/transcribe and the same transcript comes back with a speaker number on every word and the speech grouped into utterances. This endpoint adds the speaker segments (diarization) and the speaker-labeled text merged with them (merged), and its results can feed Diarization + sentiment.

## Example request

Works like [Transcribe](/speech-to-text/transcribe), with speaker labels added to the response.

```bash
curl -X POST "https://api.munsit.com/api/v1/audio/diarization/transcribe" \
  -H "x-api-key: $MUNSIT_API_KEY" \
  -F "file=@interview.mp3" \
  -F "model=munsit"
```

```python
import requests, os

r = requests.post(
    "https://api.munsit.com/api/v1/audio/diarization/transcribe",
    headers={"x-api-key": os.environ["MUNSIT_API_KEY"]},
    files={"file": open("interview.mp3", "rb")},
    data={"model": "munsit"},
)
for seg in r.json()["data"]["merged"]:
    print(seg["speaker"], seg["text"])
```

```javascript
import fs from "node:fs";

const form = new FormData();
form.append("file", new Blob([fs.readFileSync("interview.mp3")]), "interview.mp3");
form.append("model", "munsit");

const res = await fetch(
  "https://api.munsit.com/api/v1/audio/diarization/transcribe",
  { method: "POST",
    headers: { "x-api-key": process.env.MUNSIT_API_KEY },
    body: form }
);
const { data } = await res.json();
for (const seg of data.merged) console.log(seg.speaker, seg.text);
```

```go
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
)

func main() {
	var buf bytes.Buffer
	w := multipart.NewWriter(&buf)
	f, _ := os.Open("interview.mp3")
	fw, _ := w.CreateFormFile("file", "interview.mp3")
	io.Copy(fw, f)
	w.WriteField("model", "munsit")
	w.Close()

	req, _ := http.NewRequest("POST",
		"https://api.munsit.com/api/v1/audio/diarization/transcribe", &buf)
	req.Header.Set("x-api-key", os.Getenv("MUNSIT_API_KEY"))
	req.Header.Set("Content-Type", w.FormDataContentType())

	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	var out map[string]any
	json.NewDecoder(resp.Body).Decode(&out)
	data := out["data"].(map[string]any)
	for _, seg := range data["merged"].([]any) {
		s := seg.(map[string]any)
		fmt.Println(s["speaker"], s["text"])
	}
}
```

Response — 200

```
{
  "statusCode": 200,
  "data": {
    "transcription": {
      "transcription": "السلام عليكم ورحمة الله وبركاته. كيف حالك اليوم؟",
      "timestamps": [
        { "word": "السلام", "start": 0.0, "end": 1.2 }
      ]
    },
    "diarization": {
      "segments": [
        { "start": 0.0, "end": 8.5, "speaker": "SPEAKER_00" }
      ]
    },
    "merged": [
      {
        "start": 0.0,
        "end": 8.5,
        "speaker": "SPEAKER_00",
        "text": "السلام عليكم ورحمة الله وبركاته"
      }
    ],
    "duration": 53.661375
  },
  "message": "Success"
}
```

## Response fields

Three views of the same audio arrive under `data`: the raw transcript, the speaker segments, and the two merged together.

| Field | Type | Description |
| --- | --- | --- |
| `transcription` | object | Transcript and word-level timestamps. |
| `diarization` | object | Speaker segments with start/end labels. |
| `merged` | array of objects (`start`, `end`, `speaker`, `text`) | Combined diarization + transcript. |
| `duration` | number | Total duration in seconds. |
| `transcriptionId` | string (UUID) | Transcription identifier. Use it as the path parameter for [diarization sentiment analysis](/speech-to-text/diarization-sentiment). |
| `originalTranscript` | string | Raw verbatim transcript. |
| `attributes` | object | Internal metadata blob persisted with the transcription. Prefer the named fields — treat this as unstable. |
| `stats` | object (`fileName`, `fileSize`, `mimeType`, `creditsConsumed`) | Upload metadata and the credits billed for this request. |

> Most apps only need merged. Each entry is one speaker turn — speaker, its text, and start/end timing — ready to render as a conversation.

## Go further

What to run on a diarized conversation next.

- [Diarization + sentiment →](/speech-to-text/diarization-sentiment) — Analyze per-speaker sentiment from a diarization record. — `POST /diarization/{diarizationId}/sentiment-analysis`

- [Transcribe →](/speech-to-text/transcribe) — Plain transcription when you don't need speaker labels. — `POST /audio/transcribe`

- [Minutes of meetings →](/speech-to-text/minutes-of-meetings) — Structured meeting transcripts for documentation. — `POST /minutes-of-meeting/transcribe`

- [Keyword extraction →](/understanding/keyword-extraction) — Pull the key topics out of the conversation. — `POST /keyword-extraction`
