# Authentication

Every paid call carries an API key. A key belongs to your account, spends its credit balance, and can be revoked in one click.

## API keys

Create a key in the dashboard under [API keys](https://app.zomler.com/api-keys). Give it a name that says where it will live — *staging*, *the CRM sync* — and, if you want a hard stop, an expiry. The full key is shown **once**, at creation; after that only its first characters are visible, so you can match it to a config file but never read it back.

Keys start with `zk_live_`. Store them as secrets, never in client-side code: anyone holding a key can spend the balance it is attached to.

## Sending the key

Either header works; use whichever your HTTP client makes easy.

**Headers**

```
X-API-Key: zk_live_…

# or

Authorization: Bearer zk_live_…
```

A request without a valid key answers `401` with `error.code = "unauthorized"`. Unknown, revoked and expired keys get the same answer on purpose — the response never says which.

## What a key can do

A key can run every platform op and read the balance. It cannot manage keys, change billing or reach anything in the dashboard — those need a signed-in session.

The dashboard shows, per key, how many calls it has made and how many credits it has spent, so a leaked or runaway key is visible as a line item and not as a surprise on the balance.

Revoking is immediate and cannot be undone. In-flight calls finish; the next one is a `401`. Anything already fetched stays in your account — revoking access is not a refund.

## Checking the balance

`GET https://api.zomler.com/api/v1/balance` with your key returns the spendable credits. You rarely need it: every response carries `cost.creditsRemaining`, so a loop can watch its own budget without a second call.

```bash
curl https://api.zomler.com/api/v1/balance \
  -H "X-API-Key: zk_live_…"
```

---

Source: https://zomler.com/docs/api/authentication
