# API Keys

> Create named live and test Avox API keys for one WhatsApp number, confirm sensitive changes with an emailed code, rotate keys without losing their limits, revoke them, and read every request on the API logs page.

Source: https://docs.theavoxai.com/connections/api-keys

An Avox API key lets your own server send WhatsApp messages from one of your connected numbers
through the [Avox API](https://docs.theavoxai.com/avox-api). Your server holds only the Avox key - Meta's access token for the
number stays with Avox.

```
POST https://api.avox.com/api/messages/send
Authorization: Bearer avx_live_...
```

You manage keys in two places:

- **The connection's page** - the **Outbound API keys** section lists, creates, rotates and revokes
  keys for that one connection.
- **Settings > API Keys** - every key across all your connections, plus **Test**, **Rotate**, each
  key's recent requests, and security warnings.

Every request made with your keys, and every message forwarded to your endpoint, is on the
[API logs](#api-logs) page.

## Who can do what

| Action | Admin | Manager |
| --- | --- | --- |
| See keys and when they were last used | Yes | With **See API keys** |
| **Test** a key | Yes | With **Manage API keys** |
| See the [API logs](#api-logs) and export them as CSV | Yes | Yes |
| Create a live or test key | Yes, with an emailed code | With **Manage API keys**, and an emailed code |
| Rotate a key | Yes, with an emailed code | With **Manage API keys**, and an emailed code |
| Revoke a key | Yes, with an emailed code | With **Manage API keys**, and an emailed code |
| Resend a forwarded message from the logs | Yes | No |

An Admin gives a Manager **See API keys** or **Manage API keys** on the
[Members](https://docs.theavoxai.com/switchboard/members) page. Without **Manage API keys**, the connection's page reads "Only
people who can manage API keys in this Switchboard can create, rotate or revoke them."

## Confirmation codes

Creating, rotating and revoking a key each need a 6-digit code that Avox emails to **you** - the
person doing it - at your sign-in address. It's the same code box used for two-factor sign-in.

- A code works **once**, for **10 minutes**, and only for the one action and the one key (or number,
  for a new key) it was sent for. A code sent to revoke one key can't revoke another, and a code for
  revoking can't be used to rotate.
- Asking for a new code cancels the earlier one. **Resend code** is available after a minute.
- After **5 wrong tries** the code stops working, even if the right digits are typed next: "Too many
  wrong codes. Ask for a new code and try again." ([AVX-3242](https://docs.theavoxai.com/error-codes/avx-3242)).
- A wrong or expired code shows "That code is wrong or has expired. Check the email, or ask for a new
  code." ([AVX-3241](https://docs.theavoxai.com/error-codes/avx-3241)).
- Avox checks the action first, so you never get a code for something that would be refused anyway
  (a name that's already used, a key that's already revoked).

Deleting a Switchboard uses the same kind of code - see [Settings](https://docs.theavoxai.com/settings).

## How keys work

- **One key, one number.** Every key belongs to exactly one connection and always sends from that
  number. Nothing in a request can point it at another number or Switchboard.
- **Live or test.** Live keys start with `avx_live_` and send real messages. Test keys start with
  `avx_test_` and never send anything - see [Live and test keys](#live-and-test-keys).
- **Shown once.** The full key appears only once, right after you create or rotate it, and Avox can't
  show it again - copy it straight into your server's secret storage. Lost a key? Rotate it.
- **Several keys per connection.** Create one per server or environment, so you can revoke one without
  touching the others. Each has its own name - see [Key names and identity](#key-names-and-identity).
- **Sending only.** A key authenticates the Avox API. It can't sign in to the dashboard, and a
  dashboard sign-in can't send through the API. See
  [What a key can do, and what it can't](#what-a-key-can-do-and-what-it-cant).
- **Your plan decides.** Keys work only while your plan includes API access. See
  [API access and your plan](#api-access-and-your-plan).

## What a key can do, and what it can't

A key is **send-only**. It works on one endpoint, `POST https://api.avox.com/api/messages/send`, and
only sends from the number it was made for. It can't read anything back from Avox: not your contacts,
conversations, messages, templates, tags, notes, other numbers, other Switchboards, billing or account
settings. Everything else in Avox needs a dashboard sign-in, which a key can't make.

**What a request contains** - only what your server chooses to send:

- `to` - the recipient's full international number.
- `type` and the message itself: text, a template name with its language and values, a media link or
  id with an optional caption, a location, contact cards, reply buttons or a list, or a reaction. See
  [Message types](https://docs.theavoxai.com/avox-api/messages).
- Optionally `context.message_id` (to quote a message), `biz_opaque_callback_data` (your own
  reference) and an `Idempotency-Key` header.

**What the response returns:**

| Field | What it is |
| --- | --- |
| `ok` | `true` when the message was handed to WhatsApp, `false` when it wasn't. |
| `request_id` | Avox's id for the request, also in the `X-Request-Id` header. |
| `message_id` | WhatsApp's id for the message (`wamid...`), on a successful send. |
| `result` | WhatsApp's own reply to the send: the number you sent to, the recipient's WhatsApp id, and the message id. |
| `test` | Only on [test key](#live-and-test-keys) responses: `true`. |
| `error` | Only on a failure: a stable `code`, a plain `message`, a `docs_url`, the `request_id`, and when they apply `details` (which fields to fix) and `meta_code` (WhatsApp's own error number). The HTTP status says what kind of failure it is. See [API errors](https://docs.theavoxai.com/api/errors). |

That's all a key ever gets back. Delivery statuses (sent, delivered, read, failed) are on
[Logs](https://docs.theavoxai.com/logs). Messages your customers send reach your own server through
[Message forwarding](https://docs.theavoxai.com/connections/webhook-override), which an Admin turns on for each number - see
[What gets forwarded](https://docs.theavoxai.com/connections/webhook-override#what-gets-forwarded) - or through an
automation's [Send to webhook](https://docs.theavoxai.com/automation/actions#send-to-webhook) step, if you add one.

## API access and your plan

API access depends on your plan: each plan either includes it or doesn't. The plan cards on
[Plans](https://docs.theavoxai.com/plans) and on **Billing > Change plan** list **API access** on the plans that include it.

On a plan without API access:

- **Settings > API Keys** and the connection's **Outbound API keys** section read "API access isn't
  included in your plan", with a **See plans with API access** link to **Billing > Change plan**.
- Your keys stay listed, with their logs, and you can still revoke them. New keys can't be created and
  existing keys can't be rotated.
- Existing keys stop sending: requests return [`api_not_in_plan`](https://docs.theavoxai.com/api/errors#api_not_in_plan) (HTTP
  403), and **Test** on a key says so too.
- Move to a plan with API access and the same keys work again (allow up to a minute) - nothing to
  create or redeploy.

A paused plan has no API access either: the notice reads "Your plan is paused", keys can't send
(requests return [`subscription_inactive`](https://docs.theavoxai.com/api/errors#subscription_inactive)), and they work again
once you resume your plan on [Billing](https://docs.theavoxai.com/billing). With no active plan at all, the notice asks you to
pick a plan with API access.

## Key names and identity

Every key has its own identity, shown wherever keys appear - the connection's page, **Settings > API
Keys**, the [API logs](#api-logs) and Avox support's tools:

- **Name** - required, 2 to 60 characters, and different from every other working key in the
  Switchboard (capital letters and extra spaces are ignored, so "Shop key" and "shop  KEY" count as the
  same). Revoked keys, and an old key that is being replaced after a rotation, don't block a name. The
  form suggests one, like "Sales line live key".
- **What it's for** - an optional description, up to 300 characters, such as "Order updates from our
  Shopify store".
- **WhatsApp number** - the number it sends from, with the number partly hidden (for example
  `+91 98••••3210`).
- **Live or Test**, its first characters, **who created it** and **when**, and when it was **last used**.
- **Its own limits** - any [allowed IPs and limits](#allowed-ips-and-limits) Avox support set on it.

Name a key after the system that uses it ("Website orders live key", "CRM sync test key") so the
logs and any security warning point straight at the right server.

## Live and test keys

When you create a key you choose **Live key** or **Test key**:

- **Live key** - "Sends real WhatsApp messages from this number. Counts toward your limits."
- **Test key** - "Never sends anything. Checks your requests and answers with a pretend result, so you
  can build and test safely."

|  | Live key (`avx_live_...`) | Test key (`avx_test_...`) |
| --- | --- | --- |
| Sends a real WhatsApp message | Yes | Never |
| Checks the key, number, plan, limits and request body | Yes | Yes - exactly the same checks |
| Response | WhatsApp's answer, with a real `message_id` | A pretend success with a `wamid.TEST...` id, `"test": true`, and the `Avox-Test-Mode: true` header |
| Rate limits | [Live limits](https://docs.theavoxai.com/avox-api/rate-limits) | Separate [test limits](https://docs.theavoxai.com/avox-api/rate-limits#test-keys) - test traffic never uses up your live allowance |
| In the API logs | **Live** badge | **Test** badge |

Use a test key while you build and in your automated tests, and a live key in production. Special test
numbers let you trigger each kind of error on purpose - see [Testing](https://docs.theavoxai.com/avox-api/testing).

## Create a key in Settings

**1. Step 1**

API Keys">
   Open **Settings**, choose the **API Keys** tab, and click **Create a key**.

**2. Pick the Switchboard and the WhatsApp number**

**Switchboard** starts on the one you're in; the list only has Switchboards where you can manage
keys. If the Switchboard has more than one number, open **WhatsApp number** and pick one - each
shows its name, the number partly hidden, and whether it's **Connected** or **Paused**. Avox never
picks a number for you; without one you see "Choose which WhatsApp number this key sends from."
([AVX-3245](https://docs.theavoxai.com/error-codes/avx-3245)).

**3. Choose Live key or Test key**

The card under each choice says what it does.

**4. Name the key**

**Key name** is filled in for you (for example "Sales line live key") - change it to something
you'll recognise. Optionally add **What it's for**. See
[Key names and identity](#key-names-and-identity).

**5. Click Email me a code**

Avox emails a 6-digit code to your sign-in address. Type it in the boxes - the key is created as
soon as the last digit is in. See [Confirmation codes](#confirmation-codes).

**6. Copy the key**

The **Your new API key** dialog shows the full key: "Copy it now - Avox only ever stores its hash,
so this is the only time it's shown." A test key adds "This is a test key: requests made with it
never send a real message." Click the copy button ("Copied"), store the key in your server's secret
storage, then click **Done**.

With no connected numbers, the card reads "Connect a WhatsApp number first - a key always sends from
one number." The **How this works** button opens this page, and **API logs** opens the
[API logs](#api-logs). A key you create in another Switchboard shows up in that Switchboard's list.

## Create a key on the connection's page

On [Connections](https://docs.theavoxai.com/connections), click **Settings** on the number, scroll to **Outbound API keys** and
click **Create a key for this number**. It's the same form with the Switchboard and number already
set: choose Live or Test, name the key, click **Email me a code**, and type the code. With no keys yet
the section reads "No key yet - create one when your server is ready to send through Avox."

Each key in the list shows its name, first characters, a **Live** or **Test** badge, the number, what
it's for, who created it and when, when it was last used, any limits, **Rotate**, and a bin button to
revoke it. Under the list, **API logs** opens this number's requests and **Settings > API keys** opens
every key.

## The Settings > API Keys tab

 API Keys: the Create a new key card with API logs, How this works and Create a key, above Active keys listing a Test key and a Live key with Test, Rotate and revoke buttons." caption="Two active keys on one number: a test key for staging and a live key for production. Only the first characters of each key are ever shown." />

### Active keys

Each key shows:

- **Its name, first characters**, a **Live** or **Test** badge, and the WhatsApp number it sends from
  (name and partly hidden number).
- **What it's for**, when the key has a description.
- **Created** - the date and who created it - and **Last used** ("just now", "5m ago", "3h ago", or a
  date; "Never" until it's used).
- **Limits** - any per-minute, daily or allowed-IP limits on the key, with "(kept when you rotate)".
- **Expires in ...** in amber, with "replaced by ..." and the new key's first characters, for an old
  key that was [rotated](#rotate-a-key) and is still in its grace period.
- **Test** - see [Test a key](#test-a-key).
- **Rotate** - see [Rotate a key](#rotate-a-key).
- **The arrow** - shows the key's [recent requests](#recent-requests).
- **The bin** - revokes the key. See [Revoke a key](#revoke-a-key).

With no keys, the card reads "No active keys yet."

### Revoked and expired keys

Revoked keys, and old keys whose rotation grace period has ended, move to their own **Revoked and
expired keys** card, crossed out with a **Revoked**, **Rotated** or **Expired** badge, so you keep a
record of every key that existed. A key the Avox team revoked also shows "Revoked by the Avox team"
with their reason.

## Rotate a key

Rotating swaps a key for a new one without downtime. **Nothing is reset**: the new key gets the old
key's name, number, mode (live or test), description and the [limits](#allowed-ips-and-limits) it has
at that moment - allowed IPs, the per-minute limit and the daily allowance. The counts carry on too:
requests made with the old key today still count toward the new key's daily allowance, and both keys
share the per-minute limit while both work. So rotating is never a way around a limit.

**1. Click Rotate on the key**

In **Settings > API Keys** or on the connection's page. The **Rotate ...?** dialog shows the key,
its number and its limits, and explains that you'll get a new key with the same name, number,
description and limits, and that both keys work until the old one stops.

**2. Choose when the old key stops working**

Under "When should the old key stop working?", pick **Immediately**, **In 1 hour**, **In 24 hours**
(the default) or **In 7 days**. Choosing **Immediately** warns "Anything still using the old key
gets "key expired" errors straight away."

**3. Click Email me a code to rotate, and type the code**

The key is rotated as soon as the last digit is in. See [Confirmation codes](#confirmation-codes).

**4. Copy the new key**

The **Your rotated API key** dialog shows the new key once, and says how long the old one keeps
working - for example "The old key keeps working for 24 hours, then stops."

**5. Put the new key on your server**

Deploy it everywhere the old key was used. On the old key, "Expires in ..." counts down.

When the grace period ends, requests with the old key return `key_expired`
([API errors](https://docs.theavoxai.com/api/errors#key_expired)) and it moves to **Revoked and expired keys** with a
**Rotated** badge. Check the [API logs](#api-logs) filtered to the old key: once nothing uses it,
you're done. Choose **Immediately** only when the old key may have leaked - anything still using it
fails at once.

A key can be rotated once; to rotate again, rotate its replacement. Both changes are written to your
Switchboard's activity log, and every Admin gets the "API key created" email for the new key. If
rotating fails, you see "Couldn't rotate that API key. Your current key still works - try again."
([AVX-3105](https://docs.theavoxai.com/error-codes/avx-3105)).

## Test a key

**Test** is a safe dry run. It checks that the key is active, that its connection is connected, and
that the connection is ready to send - **without** sending a WhatsApp message or using any Meta
credit. Admins, and Managers with **Manage API keys**, can run it from **Settings > API Keys**.

| Result | What to do |
| --- | --- |
| Working - routes to Support EU. | Nothing - the key is ready to send from that connection. A test key adds "Test key: sends are simulated, nothing reaches WhatsApp." |
| This key has been revoked - create a new one to test. | Create a new key. |
| This key has expired - use the key that replaced it, or create a new one. | The key was rotated and its grace period ended. Use the new key. |
| This key's connection no longer exists. | The connection was deleted. Create a key for a current connection. |
| This key's connection is paused - resume it to send. | Resume the connection on [Connections](https://docs.theavoxai.com/connections), or fix billing if it was paused for payment. |
| This key's connection isn't active right now. | Check the connection on [Health](https://docs.theavoxai.com/health). |
| This connection needs to be reconnected before it can send. | Connect the number again with the [setup wizard](https://docs.theavoxai.com/connections/setup). |
| API access isn't included in your plan, so this key can't send. Move to a plan with API access and it works again. | Move to a plan with API access on **Billing > Change plan**. See [API access and your plan](#api-access-and-your-plan). |
| This account doesn't have an active plan, so this key can't send. | Renew or resume your plan on [Billing](https://docs.theavoxai.com/billing). |
| API access is turned off for this account. Contact support if you need it. | Contact [Support](https://docs.theavoxai.com/support). |
| Couldn't verify that key. Try again. | Try again ([AVX-3055](https://docs.theavoxai.com/error-codes/avx-3055)). |

Each test is recorded with the source **Test** and the endpoint "Dashboard test", kept apart from real
sends. To test your own code end to end, use a [test key](https://docs.theavoxai.com/avox-api/testing).

## Recent requests

Click the arrow on a key to open **Recent requests** - the key's latest 20 requests, newest first, with
a **See all in API logs** link that opens the logs filtered to that key. Each row shows:

- **A green tick or red cross** - whether the request succeeded.
- **Send** or **Test** - a real API request, or a dashboard test.
- **The HTTP status** returned, such as `200` or `409`.
- **The recipient, masked** - only a few digits of the number are shown.
- **The error code**, linked to its explanation on [API errors](https://docs.theavoxai.com/api/errors), or **Replayed** when an
  [idempotent retry](https://docs.theavoxai.com/avox-api/idempotency) returned the original result.
- **The IP address** the request came from.
- **When** it happened.

With no requests, it reads "No requests logged yet - this key hasn't been used." If the list doesn't
load, you see "Couldn't load recent activity for that key." ([AVX-3056](https://docs.theavoxai.com/error-codes/avx-3056)).

## API logs

**API logs** is in the sidebar under **Connection** (and in search) once the Switchboard has at least
one API key - live, test, revoked or expired. Before that it's hidden, and opening the page directly
shows "No API keys in this Switchboard yet" with a **Create an API key** button. It's also linked from
**Settings > API Keys** (the **API logs** button), from each key's **See all in API logs**, and from
each connection's **Outbound API keys** section. The header reads "Every request made with your API
keys, and every message forwarded to your endpoint.", with **API keys** and **Docs** buttons.

### The two tabs

| Tab | Columns |
| --- | --- |
| **Sent** | Every request made with your API keys, including dashboard tests: **Time**, **Key** (name with its **Live** or **Test** badge), **Connection**, **Endpoint**, **Outcome** (a tick or cross, the HTTP status, and the error code linked to [API errors](https://docs.theavoxai.com/api/errors), or "replayed"), **Recipient** (masked), **Request ID** and **Latency** (how long Avox took to answer, in ms). |
| **Received** | Every incoming message Avox forwarded to your endpoint with [message forwarding](https://docs.theavoxai.com/connections/webhook-override): **Time**, **Connection**, **Event** (with a **Test** badge for test events), **Message ID**, **Delivery** (Queued, Sending, Retrying, Delivered or Failed), **Attempts** and **Response** (your endpoint's HTTP code). |

### Filters and search

| Filter | Options |
| --- | --- |
| Key (Sent only) | **All keys**, or one key. Each key in the list shows its name, a **Live** or **Test** badge, its first characters and its number; revoked and expired keys are crossed out and marked. With many keys, type to search by name, first characters or number. |
| Mode | **Live and test**, **Live only**, **Test only**. On Received, this picks real messages or test events. |
| Connection | **All connections**, or one connection. |
| Status | Sent: **Any status**, **Success**, **Error**. Received: **Any status**, **Delivered**, **Failed or retrying**, **Queued or sending**. |
| Error code (Sent only) | **Any error code**, or one of the [API error codes](https://docs.theavoxai.com/api/errors). Picking one also sets Status to Error. |
| From and To | A date range. Each date covers the whole day in UTC. |

- **Search** - paste a request id (`req_...`, from the `X-Request-Id` header) or a message id
  (`wamid...`) on Sent, or a message id or event id (`evt_...`) on Received, then click **Search**.
  Search matches whole ids only - never message text or phone numbers.
- **Clear filters** resets everything.
- **Requests per key** - on Sent, a row of chips under the filters shows each key's name with the
  number of requests and errors for the chosen dates and mode. Click a chip to show only that key's
  requests; click it again to show all keys.
- Filters, search, the tab and the page number are part of the page's address, so you can bookmark or
  share a filtered view. Switching tabs clears the key, status and error code filters.

The table shows 25 rows a page, with "Page 1 of 4 · 80 requests" (or "messages" on Received) and
**Previous** / **Next** when there are more.

| Empty state | Meaning |
| --- | --- |
| No API requests yet. Requests made with your keys show up here within seconds. | None of your keys has been used. |
| No requests match those filters. / No forwarded messages match those filters. | Loosen or clear the filters. |
| Nothing forwarded yet. Turn on message forwarding on a connection's page to send incoming messages to your server. | See [Message forwarding](https://docs.theavoxai.com/connections/webhook-override). |

### Details

Click any row (or select it and press `Enter`) to open its details in a sidebar beside the
table on a wide screen, or under the table on a narrower one. The table stays usable while it's open: the
selected row is highlighted, `↑` and `↓` move to the previous or next row, and
`Esc` (or the close button, or clicking the row again) closes the details. Each section of the
details can be collapsed on its own.

- **Request details** (Sent):
  - **Request** - **Key** (name, first characters and mode), **Endpoint**, **Connection**,
    **Recipient** (masked), **Request ID** with a copy button, **Source** ("Your server" or "Test button
    in the dashboard") and **IP address**.
  - **Response** - the outcome with the HTTP status and the **Message ID** with a copy button. An
    idempotent replay shows "Replayed from an earlier request with the same Idempotency-Key. Nothing was
    sent again."
  - **Error** (only when it failed) - the error code and a link to what it means and how to fix it.
  - **Timing** - the time (also in full UTC) and the latency.
  - **Related forwarding delivery** - **Show forwarded events for this message** opens the Received tab
    searched by the message ID, so you can see the status updates and replies forwarded to your endpoint.
- **Forwarded message** (Received):
  - **Request** - **Event type**, **Connection**, **Event ID** and **Message ID** with copy buttons. The
    message itself isn't shown - read it in your Inbox.
  - **Response** - delivery status, your endpoint's **Response code** and **Attempts**.
  - **Error** (when it failed or is retrying) - the last error and a link to how retries work.
  - **Timing** - when it was received, delivered, and the **Next try** for a delivery that's retrying.

On a forwarded message, an Admin sees **Resend to your endpoint** at the bottom of the details ("Already
on its way" while it's queued or sending). Resending needs forwarding to be on, keeps the same event
id, and shows "Queued - it goes out to your endpoint in a few seconds."

### Export CSV

**Export CSV** downloads every row that matches the current tab, filters and search - newest first, up
to 10,000 rows - as `avox-api-logs-sent-<date>.csv` or `avox-api-logs-received-<date>.csv`. Times are
in UTC. The file opens safely in Excel or Google Sheets. The button is turned off when nothing
matches.

| Tab | CSV columns |
| --- | --- |
| Sent | Time (UTC), Key name, Key prefix, Mode, Connection, Endpoint, Status code, Outcome, Error code, Recipient (masked), Request ID, Message ID, Latency (ms), IP address |
| Received | Time (UTC), Connection, Event type, Event ID, Message ID, Test event, Delivery status, Attempts, Response code, Last error, Delivered at (UTC) |

### What the logs contain

The logs never contain message content, forwarded payloads or full phone numbers - recipients are
masked when the request is recorded. Admins and Managers can read them. If the page doesn't load, you
see "Couldn't load your API logs. Try again." with a **Try again** button
([AVX-3106](https://docs.theavoxai.com/error-codes/avx-3106)); if an export fails, "Couldn't export your API logs. Try again."
([AVX-3107](https://docs.theavoxai.com/error-codes/avx-3107)).

For the events Meta sends Avox about your number (messages, statuses, template updates, calls), see
[Logs](https://docs.theavoxai.com/logs).

## Security warnings

Avox watches how each live key is used. When something looks unusual, the key gets an amber border, a
warning appears under it in **Settings > API Keys**, and the **Active keys** card reads, for example,
"1 key needs your attention - see the warning below."

| Warning | What happened | Revoke? |
| --- | --- | --- |
| **Used from a new place** | The key was used from an IP address it hasn't been used from before. | If you don't recognise it |
| **Blocked request from an unknown address** | A request came from an address that isn't on the key's allowed list and was stopped. | If you don't recognise it |
| **Far more requests than usual** | The key sent far more requests in an hour than it normally does. | If you didn't expect it |
| **Requests are failing** | Many requests failed in 15 minutes - usually a bug in the calling code. Check the [API logs](#api-logs). | Usually not |
| **Hit its per-minute limit** | Extra requests were refused for going over the key's per-minute limit. | No - slow down the sender |
| **Hit its daily limit** | The key used its daily allowance and works again tomorrow (UTC). | No |

When the key may be in the wrong hands, the warning reads "If you don't recognise this, rotate or
revoke this key - a revoked key stops working immediately." Revoking clears the key's warnings.

Every Admin also gets an email when a key is used from a new IP address or a request is blocked. See
[Emails about API keys](#emails-about-api-keys).

## Allowed IPs and limits

On request, Avox support can set extra rules on a key:

- **Allowed IP addresses** - the key works only from the addresses you list. Requests from anywhere
  else return `ip_not_allowed` ([API errors](https://docs.theavoxai.com/api/errors#ip_not_allowed)).
- **A per-minute limit** - extra requests return `rate_limited` with a `Retry-After` header
  ([API errors](https://docs.theavoxai.com/api/errors#rate_limited)).
- **A daily allowance** - once used, requests return `quota_exceeded` until midnight UTC
  ([API errors](https://docs.theavoxai.com/api/errors#quota_exceeded)).

These rules belong to the key and are shown with it. Rotating a key keeps them on the new key, and the
per-minute and daily counts carry on across the rotation, so a new key never starts with a fresh
allowance. A rule change also applies to an old key that's still in its grace period. To set or change
any of them, contact [Support](https://docs.theavoxai.com/support) with the key's name and first characters. See also
[Rate limits](https://docs.theavoxai.com/avox-api/rate-limits).

## Revoke a key

Click the bin next to the key - on the connection's page or in **Settings > API Keys**. The **Revoke
...?** dialog shows the key and its number; click **Email me a code to revoke** and type the code
([Confirmation codes](#confirmation-codes)), or **Keep it** to back out. Once the code is in, the key
stops working immediately: requests with it return `key_revoked`
([API errors](https://docs.theavoxai.com/api/errors#key_revoked)). It moves to **Revoked and expired keys**, and every Admin gets
an email.

Revoke a key when:

- It may have leaked (shared in a chat, committed to code, used by someone who left) - or
  [rotate](#rotate-a-key) it with **Immediately**, which gives you the replacement in the same step.
- A security warning says it was used from somewhere you don't recognise.
- The server or integration using it is retired.

The Avox team can also revoke a key that's being misused. When they do, every Admin gets an email with
the reason, and the key shows "Revoked by the Avox team" with the reason in **Revoked and expired
keys**.

If revoking fails, you see "Couldn't revoke that API key. Try again."
([AVX-3054](https://docs.theavoxai.com/error-codes/avx-3054)).

## When keys stop working

| Situation | API error |
| --- | --- |
| The key was revoked | [`key_revoked`](https://docs.theavoxai.com/api/errors#key_revoked) |
| The key was rotated and its grace period ended | [`key_expired`](https://docs.theavoxai.com/api/errors#key_expired) |
| The connection is paused | [`connection_paused`](https://docs.theavoxai.com/api/errors#connection_paused) |
| The connection was deleted | [`connection_not_found`](https://docs.theavoxai.com/api/errors#connection_not_found) |
| The connection isn't connected | [`connection_inactive`](https://docs.theavoxai.com/api/errors#connection_inactive) |
| The connection needs to be reconnected | [`connection_not_ready`](https://docs.theavoxai.com/api/errors#connection_not_ready) |
| The subscription isn't active, or the plan is paused | [`subscription_inactive`](https://docs.theavoxai.com/api/errors#subscription_inactive) |
| Your plan doesn't include API access | [`api_not_in_plan`](https://docs.theavoxai.com/api/errors#api_not_in_plan) - see [API access and your plan](#api-access-and-your-plan) |
| API access was turned off for your account | [`api_access_disabled`](https://docs.theavoxai.com/api/errors#api_access_disabled) |

When API access is turned off for your account (whatever your plan), **Settings > API Keys** reads "API keys have been
turned off for your account, so new keys can't be created and existing ones won't send. Contact support
if you need them." and the connection's page reads "API keys have been turned off for your account -
contact support if you need them." Contact [Support](https://docs.theavoxai.com/support) to turn them back on.

## Emails about API keys

| Email | Sent to | Includes |
| --- | --- | --- |
| API key created | Every Admin | The key's name and first characters, its connection, and when it was created (also sent for the new key of a rotation). |
| API key revoked | Every Admin | Which key, and whether your team or Avox revoked it (with Avox's reason). |
| API key alert | Every Admin | A key used from a new IP address, or a request blocked by the allowed list. |

Every email links to **Settings > API Keys**. See [Emails](https://docs.theavoxai.com/emails).

## Sending your first message

```bash
curl -X POST https://api.avox.com/api/messages/send \
  -H "Authorization: Bearer $AVOX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "to": "15551234567", "type": "text", "text": { "body": "Hello from Avox!" } }'
```

With a test key the same request answers `"test": true` and sends nothing. See [Avox API](https://docs.theavoxai.com/avox-api)
for the full reference, [Authentication](https://docs.theavoxai.com/avox-api/authentication) for sending the key, and
[Message types](https://docs.theavoxai.com/avox-api/messages) for every message type.

## Errors in the dashboard

| Message | Code |
| --- | --- |
| Couldn't create that API key. Try again. | [AVX-3053](https://docs.theavoxai.com/error-codes/avx-3053) |
| Couldn't revoke that API key. Try again. | [AVX-3054](https://docs.theavoxai.com/error-codes/avx-3054) |
| Couldn't verify that key. Try again. | [AVX-3055](https://docs.theavoxai.com/error-codes/avx-3055) |
| Couldn't load recent activity for that key. | [AVX-3056](https://docs.theavoxai.com/error-codes/avx-3056) |
| Couldn't rotate that API key. Your current key still works - try again. | [AVX-3105](https://docs.theavoxai.com/error-codes/avx-3105) |
| Couldn't load your API logs. Try again. | [AVX-3106](https://docs.theavoxai.com/error-codes/avx-3106) |
| Couldn't export your API logs. Try again. | [AVX-3107](https://docs.theavoxai.com/error-codes/avx-3107) |
| Couldn't resend that message. Try again. | [AVX-3103](https://docs.theavoxai.com/error-codes/avx-3103) |
| Couldn't send the confirmation code. Try again. | [AVX-3240](https://docs.theavoxai.com/error-codes/avx-3240) |
| That code is wrong or has expired. Check the email, or ask for a new code. | [AVX-3241](https://docs.theavoxai.com/error-codes/avx-3241) |
| Too many wrong codes. Ask for a new code and try again. | [AVX-3242](https://docs.theavoxai.com/error-codes/avx-3242) |
| Another key in this Switchboard already has that name. Pick a different name. | [AVX-3243](https://docs.theavoxai.com/error-codes/avx-3243) |
| Give the key a name between 2 and 60 characters. | [AVX-3244](https://docs.theavoxai.com/error-codes/avx-3244) |
| Choose which WhatsApp number this key sends from. | [AVX-3245](https://docs.theavoxai.com/error-codes/avx-3245) |
| Couldn't load your Switchboards and numbers. Try again. | [AVX-3246](https://docs.theavoxai.com/error-codes/avx-3246) |

Some errors show a more specific line from Avox instead, for example "That key was already rotated.
Rotate its replacement instead." or "That key is revoked - create a new key instead."
