---
title: "API keys"
description: "Obtaining your API subscription key from the platform, using it, managing it, and what an auth failure means."
---

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

# API keys

The Bodhi APIs use API keys for authentication. Every request must include your
key, which authenticates the call and meters usage against your account's
credit balance.

Your key is a secret. Do not share it, and do not expose it in client-side code
such as browsers or mobile apps.

## Obtaining your API subscription key

Keys are issued from the platform at
[platform.navana.ai](https://platform.navana.ai). Signup is self-serve.

1. **Register**

   Go to [platform.navana.ai](https://platform.navana.ai) and register with
   your organisation email address. You can also sign in with Google instead.
2. **Verify your email**

   A one-time code is sent to that address. Enter it to verify the account.
3. **Complete your profile**

   Fill in your name, team size, and role. This is the last step before the
   dashboard.
4. **Open API Keys**

   Select **API Keys** in the sidebar.
5. **Create the key**

   Click **Create API Key**, give it a short name so you can recognise it
   later, and confirm.
6. **Copy it immediately**

   The key is displayed once, at creation, and cannot be retrieved afterwards.
   Copy it and store it somewhere safe before closing the dialog.

> **One active key per account**
>
> Creating a key revokes the one that was active before it, and the platform
> asks you to confirm this. There is no overlap period, so update your callers
> before you create a replacement.

## Using the API subscription key

Send the key in an `X-Api-Key` header. Here it is against the non-streaming
transcription endpoint:

```bash
curl -X POST https://stt.navana.ai/api/transcribe \
  -H "X-Api-Key: $BODHI_API_KEY" \
  -F "model=hi-banking-v2-8khz" \
  -F "transaction_id=$(uuidgen)" \
  -F "audio_file=@recording.wav"
```

```python
import os, uuid, requests

response = requests.post(
"https://stt.navana.ai/api/transcribe",
headers={"X-Api-Key": os.environ["BODHI_API_KEY"]},
data={
    "model": "hi-banking-v2-8khz",
    "transaction_id": str(uuid.uuid4()),
},
files={"audio_file": open("recording.wav", "rb")},
)
```

```ts
import { openAsBlob } from 'node:fs'

const form = new FormData()
form.set('model', 'hi-banking-v2-8khz')
form.set('transaction_id', crypto.randomUUID())
form.set('audio_file', await openAsBlob('recording.wav'), 'recording.wav')

const res = await fetch('https://stt.navana.ai/api/transcribe', {
  method: 'POST',
  headers: { 'X-Api-Key': process.env.BODHI_API_KEY! },
  body: form,
})
```

```go
file, _ := os.Open("recording.wav")
defer file.Close()

var body bytes.Buffer
form := multipart.NewWriter(&body)
form.WriteField("model", "hi-banking-v2-8khz")
form.WriteField("transaction_id", uuid.NewString())
part, _ := form.CreateFormFile("audio_file", "recording.wav")
io.Copy(part, file)
form.Close()

req, _ := http.NewRequest(http.MethodPost,
	"https://stt.navana.ai/api/transcribe", &body)
req.Header.Set("X-Api-Key", os.Getenv("BODHI_API_KEY"))
req.Header.Set("Content-Type", form.FormDataContentType())

resp, err := http.DefaultClient.Do(req)
```

The same header goes on the WebSocket upgrade for streaming. See
[Authentication](/authentication) for every endpoint, and
[Transcribe a file](/api-reference/transcribe) for the full parameter list.

## Best practices for API key management

**Keep it server-side.** Anything shipped to a browser or mobile app can be
read by whoever opens devtools, so the key should stay on your server. If a
browser needs transcription, have it talk to your backend, and let the backend
hold the key and relay audio to Bodhi.

**Read it from the environment or a secret manager**, never from source
control.

```bash
# .env (git-ignored)
BODHI_API_KEY=bd_xxxxxxxxxxxx.xxxxxxxx…
```

```python
import os

api_key = os.environ["BODHI_API_KEY"]  # raises early if unset
```

```ts
const apiKey = process.env.BODHI_API_KEY
if (!apiKey) throw new Error('BODHI_API_KEY is not set')
```

```go
apiKey := os.Getenv("BODHI_API_KEY")
if apiKey == "" {
	log.Fatal("BODHI_API_KEY is not set")
}
```

**Have every service read one shared secret.** Because creating a key revokes
the previous one, rotation is a cutover rather than a handover. If each service
holds its own copy, a rotation means updating them all before the old key dies.

**Rotate as a planned cutover.** Create the new key, push the new value, and
restart or reload your callers. In-flight requests already authorized will
finish, but new ones on the old key fail immediately.

**Alert on `401`.** After a rotation it means a caller missed the update. At
any other time it means something is wrong.

**Revoke deliberately.** Revoke from the **API Keys** page in the platform.
Revocation takes effect on the next request, since key status is checked on
every call, so there is no cache to wait out. Open streams authorized before
revocation keep running until they end on their own or run out of credits. Past
keys stay listed under **Archived keys**, with who created each one and when.

## Status codes for authentication

| Status | Meaning | What to do |
| --- | --- | --- |
| `401` | The key is missing, malformed, unrecognised, or revoked. | Check the header name and that you sent the whole `prefix.secret` value. If you recently created a key, an old one is still in use somewhere. |
| `402` | The account's credit balance is exhausted. | Top up. Retrying without topping up fails identically. |
| `403` | The account is suspended or closed, or the key does not carry the scope the endpoint needs. | An account problem needs support. A scope problem needs a different key, though every key created today is granted all scopes. |

## Related

- [Authentication](/authentication) — Where the key goes for each API.
- [Errors and debugging](/api-reference/errors) — Every status code across the API.

Source: https://docs.navana.ai/api-keys/index.mdx
