> For the full page index, fetch https://echonova.ai/llms.txt

# Get an API key

Create a key in the portal, store the secret once, and make your first authenticated request.

An API key lets your own backend call the Developer API on behalf of your
workspace. You create it in the portal, copy the secret once, and send it as a
bearer token on every request.

## What you need

- An EchoNova account and a workspace. Sign in at `/auth/sign-in`.
- The workspace owner's access, which includes the `developer_api.manage`
  permission.
- An active or trial subscription on the workspace. The API rejects keys from a
  workspace without one.
- A free slot under your plan's limit on active keys. The portal tells you when
  you are at the limit.

## Steps

### Step 1: Open the API Keys tab

Go to `/developers?tab=api-keys`, or open **Developers** in the portal and
select the **API Keys** tab. Keys you already created are listed here.

### Step 2: Create the key

Select **Create Key** and fill in the form.

| Field                                         | What to enter                                                                                                                                                   |
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Name**                                      | Required. 1 to 100 characters. Name the system that will hold the key.                                                                                          |
| **Credit Limit**                              | Optional. A whole number of credits, up to 3,000,000,000, that this key may spend per billing cycle. The − and + buttons step by 10,000. Clear it for no limit. |
| **Services**                                  | Set **Access** or **No Access** for **Text to Speech**, **Speech to Text** and **Sound Cleaning**.                                                              |
| **Allow requests made with this credential.** | On by default. Turn it off to create the key in the **Disabled** state.                                                                                         |

Select **Create**.

> [!NOTE]
> The portal will not save a key without at least one service with
> **Access**. A key made before this change with no service selected can
> still call every service, so open it and choose its services.

Shape each key for one system. A leaked key can then be disabled without
stopping anything else, and a call in the request log names the system that
made it.

**Recommended**

- `billing-service`, **Access** on **Text to Speech** only, **Credit Limit**
  a little above its normal monthly use.

**Less effective**

- `main`, **Access** on every service, no credit limit, shared by every
  system you run.

### Step 3: Save the secret

The dialog changes to **Key Created Successfully** and shows the secret under
**Secret Key**. The secret starts with `ek_`. Select **Copy** to put it on your
clipboard, or **Download JSON** to save a file named after the key that holds
it as `secret_key`.

> [!WARNING]
> The secret is shown once. After you close this dialog the portal displays
> only the first 8 characters. If you lose the secret, delete the key and
> create a new one.

### Step 4: Make a request

Send the secret as a bearer token in the `Authorization` header. This call
lists the voices your key can use:

:::tabs

```bash
curl https://api.echonova.ai/v1/text-to-speech/voices \
  -H "Authorization: Bearer YOUR_API_KEY"
```

```python
import requests

response = requests.get(
    "https://api.echonova.ai/v1/text-to-speech/voices",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
)
print(response.json())
```

```javascript
const response = await fetch('https://api.echonova.ai/v1/text-to-speech/voices', {
  headers: { Authorization: 'Bearer YOUR_API_KEY' },
});
console.log(await response.json());
```

:::

A `200` response with a list of voices means the key works.

## What happens next

- The key appears in the list with its **Name**, the first 8 characters of the
  secret, the **Created** date, the **Last Used** date and its **Status**.
- Every request that passes authentication updates **Last Used**.
- Use the switch on the row to disable or enable the key. A disabled key is
  rejected until you enable it again.
- Open the row menu to **Edit** the name, credit limit, services and state, or
  to **Delete** the key. Deleting asks you to confirm and cannot be undone.
- If the key has a credit limit, usage counts from the start of your billing
  cycle and resets on the key's first metered call of a new cycle; see
  [Credits](/docs/developers/credits#credit-limit-per-key). When usage
  passes 80% of the limit, a `spending.warning` webhook event is sent once
  per cycle. When usage reaches the limit, `spending.exhausted` is sent on
  every such call.
- A call that would cross the limit is rejected with `429`, whichever
  service it is for. Nothing is charged.

## Limits

| Limit                     | Value                                                    | Applies to                  |
| ------------------------- | -------------------------------------------------------- | --------------------------- |
| Name length               | 1 to 100 characters                                      | Create and Edit             |
| Credit limit              | Up to 3,000,000,000 whole credits, or empty for no limit | Each key, per billing cycle |
| Active keys per workspace | Set by your plan                                         | Creating a key              |
| Services a key can call   | Text to Speech, Speech to Text, Sound Cleaning           | Requests made with the key  |

## Troubleshooting

### 401 Unauthorized

The request reached the API without a usable key. One of these is true: the
`Authorization` header is missing, it does not use the `Bearer` scheme, the
token does not start with `ek_`, the key was deleted, the key is disabled,
or the account that owns it is closed.
Check the header, then check the key's **Status** in the portal.

### 403 Subscription expired or inactive

The workspace that owns the key has no active or trial subscription. Renew the
subscription, then retry.

### 403 This API key does not have access to Text-to-Speech services

The key has at least one service on **Access**, and the one you called is not
among them. The same message exists for Speech-to-Text and Sound Cleaning. **Edit** the key and
grant **Access** to the service, or use a different key.

### 429 Monthly spending limit exhausted

A call would take the key past its credit limit for this billing
cycle. Raise the limit under **Edit**, clear it for no limit, or wait for the
next cycle.

### API-key limit reached

The portal shows this dialog when your plan's count of active keys is used up.
Delete a key you no longer use, or upgrade the plan.

## FAQ

### Can I see the secret again?

No. The portal shows only the first 8 characters. Delete the key and create
a new one.

### Does one key work for every workspace?

No. A key belongs to the workspace it was created in. See
[Base URL](/docs/developers/base-url).

### What does disabling a key do?

Requests made with it get `401` until you enable it again. The key keeps its
name, credit limit, services and usage.

### What happens to the credit limit when I edit it?

The new limit applies to the next request. Usage already recorded in this cycle
stays counted.

### Who can create or delete keys?

The workspace owner, whose role has the `developer_api.manage` permission.

## Related

- [Base URL](/docs/developers/base-url)
- [Authentication](/docs/developers/authentication)
- [Developer API overview](/docs/developers/overview)
- [List available voices](/docs/reference/tts-list-voices)
- [What is EchoNova](/docs/get-started/what-is-echonova)
