# Authentication

> One API key. Create a key in the dashboard and you're done — no OAuth dance, no token exchange.

## Send your key as a header

Send your API key in the `x-api-key` HTTP header.

```
x-api-key: YOUR_API_KEY
```

> No key yet? Generate one from the dashboard at app.munsit.com (or ae.app.munsit.com for the UAE). Keys work on every endpoint immediately.

## Make an authenticated request

Paste the command below into your terminal to run your first API request. Replace `$MUNSIT_API_KEY` with your secret API key.

```bash
curl 'https://api.munsit.com/api/v1/text-to-speech/faseeh-v1-preview' \
  -H 'Content-Type: application/json' \
  -H "x-api-key: $MUNSIT_API_KEY" \
  -d '{
    "voice_id": "ar-najdi-male-2",
    "text": "مرحبا بك في فصيح",
    "stability": 0.5,
    "streaming": true,
    "speed": 1
  }'
```

```python
import requests

headers = {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
}

response = requests.post(
    'https://api.munsit.com/api/v1/text-to-speech/faseeh-v1-preview',
    headers=headers,
    json={
        'voice_id': 'ar-najdi-male-2',
        'text': 'مرحبا بك في فصيح',
        'stability': 0.5,
        'streaming': True,
        'speed': 1
    }
)
```

```javascript
const response = await fetch('https://api.munsit.com/api/v1/text-to-speech/faseeh-v1-preview', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    voice_id: 'ar-najdi-male-2',
    text: 'مرحبا بك في فصيح',
    stability: 0.5,
    streaming: true,
    speed: 1
  })
});
```

```go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	payload := []byte(`{
    "voice_id": "ar-najdi-male-2",
    "text": "مرحبا بك في فصيح",
    "stability": 0.5,
    "streaming": true,
    "speed": 1
  }`)

	req, _ := http.NewRequest("POST", "https://api.munsit.com/api/v1/text-to-speech/faseeh-v1-preview", bytes.NewReader(payload))
	req.Header.Set("x-api-key", os.Getenv("MUNSIT_API_KEY"))
	req.Header.Set("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()
}
```

Response

```
// audio stream — save and play
```

## WebSocket authentication

REST requests always use the `x-api-key` header. WebSocket endpoints accept it too, plus a query-parameter form for browsers, which cannot set headers on a WebSocket connection.

| Endpoint | Header | Query parameter |
| --- | --- | --- |
| [`WS /api/v1/listen`](/speech-to-text/streaming) — speech to text | `x-api-key` | `api_key` (or `x-api-key`) |
| [`WS /websocket/text-to-speech`](/reference/websocket) | `x-api-key` or `Authorization: Bearer` | `x-api-key` — also accepted in the `initConnection` message |

```
const ws = new WebSocket("wss://api.munsit.com/api/v1/listen?api_key=YOUR_API_KEY");
```

> Query-parameter auth puts the key in the URL. Keep connection URLs out of your logs and analytics. If authentication fails on /api/v1/listen, the connection closes with code 1008 after an Error event.

## Scope your keys

A key isn't all-or-nothing. Each key can be configured with restrictions and quotas from the dashboard.

| Control | What it does | Use it when |
| --- | --- | --- |
| **Endpoint restrictions** | Control which API endpoints each key can access — a transcription-only key can't call voice cloning. | Per-service keys, or a key you hand to a contractor. |
| **Usage limits** | Set custom quotas to manage and monitor your API consumption. | Staging keys, per-customer keys, anything you don't want running away. |

## Pick your region

The examples above use the global endpoint (`api.munsit.com`). If you're in the UAE, use the regional endpoint (`ae.api.faseeh.ai`) with an API key from the UAE dashboard. See [All endpoints](/reference/endpoints) for more details.

| Region | Base URL | Dashboard |
| --- | --- | --- |
| **Global** · default | https://api.munsit.com/api/v1 | [app.munsit.com](https://app.munsit.com/) |
| **UAE** · data residency | https://ae.api.faseeh.ai/api/v1 | [ae.app.munsit.com](https://ae.app.munsit.com/) |

> API keys are region-specific. Each endpoint requires a key from its corresponding dashboard — a key issued by the global dashboard won't authenticate against the UAE endpoint. Deploying to the UAE? Generate a separate key at ae.app.munsit.com.

## Keep it secret

Your key is a bearer credential — anyone holding it can spend your credits. Keep it secure and private.

|  | Rule | Why |
| --- | --- | --- |
| ✕ | **Never commit keys to version control** | Public repo history is scraped continuously. A leaked key is spent within minutes. |
| ✕ | **Never share a key publicly** | Anyone with the key can call the API as you and consume your quota. |
| ✕ | **Never include a key in client-side applications** | Anything shipped to the browser or a mobile app is readable. Proxy through your own backend. |
| ✓ | **Use environment variables, scope, and rotate** | Pair with the endpoint restrictions and usage limits above to bound the blast radius. |

## When it fails

Authentication and access failures come back as standard HTTP status codes with a numeric `errorCode`. The full list lives on [Errors](/errors).

| Status | Error code | Meaning | Fix |
| --- | --- | --- | --- |
| 401 | 40101 | Missing or invalid key | Check the header name is exactly `x-api-key`, and that the key hasn't expired or been revoked. In `curl`, wrap the header in **double** quotes — `'…$MUNSIT_API_KEY'` sends the literal text instead of your key. |
| 403 | 40301 | Access denied | The key or account can't reach this model or endpoint. Contact [support](/support) to request access. |
| 429 | 42901 | Concurrency limit exceeded | Wait for current requests to complete or upgrade your plan — see [Rate limits](/rate-limits). |
