# Authentication and API keys

> Authenticate Anytime Capital Payments API requests with a secret key: restrict each key to the resources it needs, and rotate or revoke keys safely.

Source: https://anytime-capital.com/docs/authentication · Markdown: https://anytime-capital.com/docs/authentication.md · All docs: https://anytime-capital.com/docs/llms-full.txt

Every request to the API at `https://anytime-capital.com/api/v1` carries a secret key from **Settings → Developers** in your dashboard, sent as a Bearer token. Keys start with `ak_live_` and act for your business with the access you give them, so they belong on your server only.

**An authenticated request**

```bash
curl "https://anytime-capital.com/api/v1/payments?limit=1" \
  -H "Authorization: Bearer $ANYTIME_API_KEY"
```

## Live and test keys

Keys made with **Test mode** on start with `ak_test_` instead. A test key works on your test data only and never moves real money; a live key never reaches test data. Both take the same permissions and work on the same URLs, and every object says which it is in `livemode`. Test keys work before your business is verified. See [Test mode](https://anytime-capital.com/docs/test-mode.md).

## Create a key

1. Open **Settings → Developers** in the Anytime Capital dashboard. Owners and admins can create keys.
2. Choose **Create key** and name it after where it will be used, such as “Website backend” or “Claude”.
3. Choose its access: **Full access**, **Read only**, or **Custom** to pick none, read or write for each resource.
4. Optionally, give it an expiry date and the IP addresses it may be used from (see below).
5. Copy the key straight away. It is shown once, in full, and never again: we keep only a hash of it.
6. Store it as a secret environment variable on your server, for example `ANYTIME_API_KEY`.

> **Keep keys on the server:** Never put a key in a browser, a mobile app, a public repository or a log. Anyone holding it can do whatever the key is allowed to: give each integration only the access it needs. If a key may have leaked, revoke it in Settings → Developers and create a new one.

## Restricted keys and permissions

Each key has an access level per resource: none, read or write (write includes read). **Full access** is write for everything, including resources added to the API later; **Read only** is read for everything. Payouts, disputes and events can only be read. Owners and admins can change a key's access at any time with **Edit** in Settings → Developers: it applies from the key's next request, and the change (before and after) is in the activity log. Keys created before restricted keys existed keep full access.

A request the key isn't allowed to make answers `403 PERMISSION_DENIED`, and the message names the permission it needs, such as `refunds:write`. The [OpenAPI document](https://anytime-capital.com/docs/openapi.md) lists the permission on every operation as `x-anytime-permission`, and each endpoint in the API reference shows it.

| Resource | Covers | Levels | Endpoints (level needed) |
| --- | --- | --- | --- |
| `payments` | Payments | None, read, write | `GET /payments` (read), `GET /payments/{id}` (read) |
| `refunds` | Refunds | None, read, write | `GET /refunds` (read), `POST /refunds` (write), `GET /refunds/{id}` (read) |
| `payment_links` | Payment links | None, read, write | `GET /payment-links` (read), `POST /payment-links` (write), `GET /payment-links/{id}` (read), `POST /payment-links/{id}` (write), `POST /payment-links/{id}/deactivate` (write) |
| `invoices` | Invoices | None, read, write | `GET /invoices` (read), `POST /invoices` (write), `GET /invoices/{id}` (read), `POST /invoices/{id}/send` (write) |
| `customers` | Customers | None, read, write | `GET /customers` (read), `POST /customers` (write), `GET /customers/{id}` (read), `PATCH /customers/{id}` (write) |
| `products` | Products | None, read, write | `GET /products` (read), `POST /products` (write), `GET /products/{id}` (read), `PATCH /products/{id}` (write), `POST /products/{id}/archive` (write) |
| `subscriptions` | Subscriptions | None, read, write | `GET /subscription-plans` (read), `POST /subscription-plans` (write), `GET /subscription-plans/{id}` (read), `GET /subscriptions` (read), `GET /subscriptions/{id}` (read), `POST /subscriptions/{id}/cancel` (write), `POST /subscriptions/{id}/pause` (write), `POST /subscriptions/{id}/resume` (write), `GET /meters` (read), `GET /meters/{id}/usage` (read), `POST /meter-events` (write), `POST /meter-events/batch` (write) |
| `discount_codes` | Discount codes | None, read, write | `GET /discount-codes` (read), `POST /discount-codes` (write), `GET /discount-codes/{id}` (read), `POST /discount-codes/{id}/deactivate` (write) |
| `payouts` | Payouts | None, read | `GET /payouts` (read), `GET /payouts/{id}` (read), `GET /balance` (read) |
| `disputes` | Disputes | None, read | `GET /disputes` (read), `GET /disputes/{id}` (read) |
| `webhook_endpoints` | Webhook endpoints | None, read, write | `GET /webhook-endpoints` (read), `POST /webhook-endpoints` (write), `GET /webhook-endpoints/{id}` (read), `PATCH /webhook-endpoints/{id}` (write), `DELETE /webhook-endpoints/{id}` (write), `POST /test-helpers/events` (write) |
| `events` | Events | None, read | `GET /events` (read), `GET /events/{id}` (read) |

For example, an online shop plugin needs `payment_links` write and `payments` read, and a reporting tool needs **Read only**. Paths are under `/api/v1`. Keys for AI agents: presets per use case are on [Safe AI agents](https://anytime-capital.com/docs/ai-agent-safety.md).

## Who can use the API

Live keys work once your business is verified and set up for card payments. Until then every request with a live key answers `403 NOT_ENROLLED`; finish verification in **Settings → Verification**. Test keys work straight away.

## Managing keys

- A business can hold up to 10 active keys at once. Use one per integration so you can revoke one without touching the others.
- Settings → Developers lists each key by name, its first characters and last four, its access, its expiry and allowed IPs, and its last request: when, from which IP address and to which endpoint. Creating, editing, rolling and revoking keys are all recorded in the activity log.
- **Edit** changes a key's name, access, expiry and allowed IP addresses. Its secret stays the same; changes apply from its next request.
- Revoking a key takes effect immediately: requests with it fail with `401 UNAUTHORIZED`, exactly like an unknown key.

## Rolling a key

**Roll** gives a key a new secret, with the same name, access, expiry and allowed IPs, shown once like a new key. The old secret keeps working for the overlap you choose (1 hour, 24 hours, 3 days, 7 days, or not at all), then expires and is revoked automatically. Deploy the new secret within the overlap and nothing fails in between. If a key may have leaked, roll it with no overlap, or revoke it.

## Expiry

A key can be given an expiry date when it is created or later, up to three years ahead. From that moment requests with it answer `401 API_KEY_EXPIRED`, naming when it expired, and it is revoked within the hour. Keys without one never expire.

Your owners and admins are reminded by email and in the dashboard a week before a key expires, a day before, and once it has expired, with the key's name, mode, last use and a link to roll it. Each chooses how in **Settings → Notifications** (API key expiring). A rolled key keeps its expiry, so edit the new key's expiry to keep it working longer. Test-mode keys are reminded too, marked as test.

## IP allowlists

Restrict a key to the addresses your servers call from: up to 20 IPv4 or IPv6 addresses or CIDR ranges, such as `203.0.113.7`, `203.0.113.0/24` or `2001:db8::/32`. A request from anywhere else answers `403 IP_NOT_ALLOWED` with the address we saw, before it counts towards the key's rate limit. Leave the list empty to allow any address. MCP tool calls are checked against the address of the AI tool calling the MCP server.

## Request IDs and the request log

Every API response carries a `Request-Id` header, such as `req_8fK2mQ9xLp3VtR7wZc4N1bYd`. **Settings → Developers → Request log** lists every request made with your keys over the last 30 days, MCP tool calls included: method, path, status, latency, IP address, Idempotency-Key, request ID and error code. Filter by key, status, method or time, or search by request ID, idempotency key, error code or path. Request and response bodies, and keys, are never logged. Quote the request ID when you contact support; the [Node SDK](https://anytime-capital.com/docs/quickstart.md#node-sdk) puts it on every error as `requestId`.

## What a key does on your behalf

Everything a key creates is attributed to the team member who created the key, and every change it makes (creating a link, an invoice or a refund, cancelling a subscription, adding a webhook endpoint…) is written to your business's activity log with the key's name, so you can always see which integration did what. A key refunds like an admin: a refund over your approval limit waits for an owner.

## Authentication errors

| Status | Code | Meaning |
| --- | --- | --- |
| 401 | `UNAUTHORIZED` | The `Authorization` header is missing, or the key is malformed, unknown or revoked. |
| 401 | `API_KEY_EXPIRED` | The key is past its expiry (or the overlap after it was rolled ended). Use its replacement. |
| 403 | `IP_NOT_ALLOWED` | The key has an IP allowlist and the request came from another address; the message names it. |
| 403 | `NOT_ENROLLED` | The key is valid but the business isn't verified and set up for card payments yet. |
| 403 | `PERMISSION_DENIED` | The key doesn't have the permission this request needs; the message names it. |
| 403 | `TEST_MODE_ONLY` | A test helper was called with a live key. Use a test key (`ak_test_…`). |
| 429 | `RATE_LIMITED` | The key went over its rate limit. See [Rate limits](https://anytime-capital.com/docs/rate-limits.md). |

## The same key works for AI tools

The MCP server at `https://anytime-capital.com/api/mcp` takes the same key in the same header, so Claude and other assistants act with exactly the access the REST API gives. See [Build with AI](https://anytime-capital.com/docs/build-with-ai.md).

---

Anytime Capital is a fintech company, not a bank. Payment processing, banking and payout services are provided by Anytime Capital's licensed partners. Rates shown are for US card payments; international cards, currency conversion and disputes may carry additional fees shown in your dashboard before you accept a payment.
