# API Keys (https://docs.billwave.example/getting-started/api-keys)

API Keys [#api-keys]

API keys authenticate your application with the Billwave API. Each key is scoped to one organization **and one environment** (sandbox or live).

Creating an API Key [#creating-an-api-key]

1. Go to **Settings → API Keys** in the dashboard
2. Click **Create New Key**
3. Enter a name (e.g. "Production Server") and pick the environment: **Sandbox** or **Live**
4. Copy the key immediately — it's only shown once!

<Callout type="warning">
  **Security**: API keys are shown only once at creation. Store them securely.
  If lost, create a new key and revoke the old one.
</Callout>

Key Format [#key-format]

```
billwave_sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx   # sandbox
billwave_sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx   # live
```

* `billwave_sk_` — Billwave secret key
* `test_` / `live_` — the environment the key is scoped to
* `xxxx…` — 48 hex characters

The prefix is not just a label. A sandbox key sent to `api.billwave.example` (or a live key sent to `sandbox.billwave.example`) is rejected with `401 environment_mismatch` before anything is written. Because the whole string is hashed for lookup, the prefix cannot be edited to change a key's scope. See [Environments](/getting-started/environments).

<Callout type="info">
  Keys created before environment scoping look like `billwave_sk_xxxx…` and are
  accepted by both environments. They still work, but cannot stop a request
  from landing in the wrong place — rotate them to scoped keys.
</Callout>

Using API Keys [#using-api-keys]

In the SDK [#in-the-sdk]

```ts
import { Billwave } from "@digvijay-x1/billwave";

// A scoped key also selects the environment (sandbox or live)
const billwave = new Billwave({
  secretKey: process.env.BILLWAVE_SECRET_KEY,
});
```

Direct API Calls [#direct-api-calls]

```bash
curl https://sandbox.billwave.example/v1/check \
  -H "Authorization: Bearer billwave_sk_test_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"customer": "user_123", "feature": "premium"}'
```

Every response includes an `X-Billwave-Environment` header (`sandbox` or `live`) and an `X-Billwave-Organization` header so you can confirm where the request landed.

In the CLI [#in-the-cli]

`billwave connect` issues a sandbox key and a live key in one approval and stores both; commands use the one matching `--mode`. In CI, set `BILLWAVE_SECRET_KEY`. See [CLI authentication](/cli/auth).

Revoking a key [#revoking-a-key]

Delete the key in **Settings → API Keys**. Requests using it fail immediately with `401`.