# Authentication, Scopes and Rate Limits

> Authenticate to the Edesy Voice Agent API with vp_live_ and vp_test_ server keys, grant per-resource read and write scopes, handle the 120 requests per minute limit and rotate keys with a 24-hour grace period.

Source: https://edesy.in/docs/voice-agent/api/authentication

Every request to the Edesy REST API (`https://voice-agent.edesy.in/api/v1`) carries a server API key: `vp_live_...` for production or `vp_test_...` for non-production. Each key belongs to one workspace and has a list of scopes, such as `agents:read` or `calls:write`. Keys are limited to 120 requests per minute by default, and rotating a key keeps the old one working for 24 hours.

## Keys

| Prefix | Use |
|--------|-----|
| `vp_live_` | Production |
| `vp_test_` | Non-production |

Create keys in **Settings → API Keys**. The key is shown once; store it in your secrets manager. Send it in either header:

```bash
curl https://voice-agent.edesy.in/api/v1/agents \
  -H "Authorization: Bearer vp_live_XXXXXXXXXXXXXXXX"

curl https://voice-agent.edesy.in/api/v1/agents \
  -H "X-API-Key: vp_live_XXXXXXXXXXXXXXXX"
```

Server keys are for your backend only. Never put one in a browser, mobile app or web page. For the website widget use a [widget key](https://edesy.in/docs/voice-agent/channels/website-widget).

A key only sees its own workspace. Asking for another workspace's resource returns `404 NOT_FOUND`.

## Scopes

| Scope | Grants |
|-------|--------|
| `agents:read` | List and read agents |
| `agents:write` | Create, update and delete agents |
| `functions:read` | List and read tools |
| `functions:write` | Create, update and delete tools |
| `calls:read` | Read calls and transcripts |
| `calls:write` | Place outbound calls |
| `phone_numbers:read` / `phone_numbers:write` | Read or manage phone numbers |
| `knowledge_base:read` / `knowledge_base:write` | Read or manage knowledge bases |
| `workflows:read` / `workflows:write` | Read or trigger workflows |

- Wildcards work: `agents:*` grants both agent scopes, and `*` grants everything.
- Write does not imply read. Grant both if you need both.
- A key with no scopes authenticates but can do nothing.
- A missing scope returns `403 INSUFFICIENT_SCOPE`, not `401`.
- The `/calls` endpoints and the workflow trigger do not enforce per-scope checks yet. Grant the right scopes anyway; enforcement will be added and correctly scoped keys will keep working.

## Rate limits

The default is **120 requests per minute per key**. Every response includes:

| Header | Meaning |
|--------|---------|
| `X-RateLimit-Limit` | Requests allowed per minute |
| `X-RateLimit-Remaining` | Requests left in the current window |
| `X-RateLimit-Reset` | Unix time (seconds) when the window resets |
| `Retry-After` | Seconds to wait (only on `429`) |

On `429 RATE_LIMIT_EXCEEDED`, wait for `Retry-After` before retrying. For bulk outbound calling, use [campaigns](https://edesy.in/docs/voice-agent/campaigns) instead of one API request per call.

## Key rotation

1. In **Settings → API Keys**, click **Rotate** on the key.
2. A new key is created first. The old key keeps working for a 24-hour grace period.
3. Deploy the new key to your services.
4. After the grace period the old key returns `401 KEY_EXPIRED`.

If a key leaks, **revoke** it instead. Revocation is immediate (`401 KEY_REVOKED`).

## Authentication errors

| Status | Code | When |
|--------|------|------|
| 401 | `MISSING_API_KEY` | No `Authorization` or `X-API-Key` header |
| 401 | `INVALID_KEY_FORMAT` | Not a `vp_live_` or `vp_test_` key |
| 401 | `INVALID_API_KEY` | The key does not match an active key |
| 401 | `KEY_REVOKED` | The key was revoked |
| 401 | `KEY_EXPIRED` | The key expired or its rotation grace period ended |
| 403 | `INSUFFICIENT_SCOPE` | The key lacks the scope for this operation |
| 429 | `RATE_LIMIT_EXCEEDED` | Over the per-key limit |

## FAQs

**Can one key work across workspaces?**
No. Create a key in each workspace.

**Is there a separate sandbox?**
Use a `vp_test_` key for non-production work. Calls placed with any key are real calls.

**Can the rate limit be raised?**
The limit is configurable per key. Contact support with your use case.

## Related

- [API overview](https://edesy.in/docs/voice-agent/api)
- [Webhook subscriptions](https://edesy.in/docs/voice-agent/api/webhook-subscriptions)
- [Security best practices](https://edesy.in/docs/voice-agent/advanced/security)
