> For a complete index of Agora Finance documentation, fetch https://docs.agora.finance/llms.txt

# Authentication

[← Switch to the Production API](/api)

> **Warning**
>
> **This is the sandbox.** It runs on testnets only. **Never send real money or real tokens to an address or bank account the sandbox returns.**
>
> The sandbox is subject to the Beta Features section of our [Terms of Use](https://static.agora.finance/termsofuse.pdf).

Sandbox authentication works the same way as production. You exchange your **API key** for a short-lived **session JWT**, then send the JWT with each call. Metrics endpoints need no authentication.

## Your sandbox API key

Agora sends you a sandbox API key when it sets up your organization. You only receive the secret once, so store it somewhere safe. To request access, a new key, or to revoke one, [fill out this form](https://qkrgh.share.hsforms.com/2PY7mSFohRvCxAuBD7resPw).

## Exchange the API key for a session JWT

Send a `POST /v0/auth/token` request with your API key in the `Authorization` header. No request body is needed.

```bash
curl -X POST https://api.sandbox.agora.finance/v0/auth/token \
  -H "Authorization: Bearer <YOUR_API_KEY>"
```

The response returns a `sessionJwt`:

```json
{
  "sessionJwt": "eyJhbGciOiJSUzI1NiIsImtpZCI6IlBfMlhSWENMIn0.eyJzdWIiOiJvcmdfa2V5XzhmMmMzZDRlIiwiaXNzIjoiaHR0cHM6Ly9hcGkuYWdvcmEuZmluYW5jZSIsImV4cCI6MTc0ODQ4NDgwMH0.signature"
}
```

The JWT is valid for **15 minutes**. The TTL is fixed and not echoed in the response, so your client should track expiry locally (or just re-exchange on any 401 with `reason: "token_expired"`).

## Make authenticated requests

Attach the session JWT as a bearer token on every authenticated endpoint:

```bash
curl https://api.sandbox.agora.finance/v0/accounts \
  -H "Authorization: Bearer <SESSION_JWT>"
```

A single JWT can be used across multiple requests until it expires. Re-exchanging on every request is unnecessary and will consume your exchange quota faster than intended.

## Refresh before expiry

There is no refresh-token endpoint. To extend a session, call `POST /v0/auth/token` again with the same API key — the previous JWT remains valid until its own expiry, so you can roll over without dropping in-flight requests.

A reasonable client pattern: exchange once at startup, cache the JWT, refresh \~60 seconds before the 15-minute expiry, and retry once on a 401 if the cached JWT was used past its lifetime.

## Error responses

Authentication failures return `401 unauthorized`, with a `context.reason` naming the cause. Where a fix says to use the dashboard, contact Agora instead. See the [Error Reference](/api/sandbox/errors#authentication-failures-401) for the full list.