> ## Documentation Index
> Fetch the complete documentation index at: https://docs.useunitpay.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> API keys, the x-api-key header, and the difference between sandbox and live.

Every request to the UnitPay API is authenticated with an **API key** sent in the `x-api-key` header. The base URL is:

```
https://api.useunitpay.com/v1
```

```bash theme={null}
curl https://api.useunitpay.com/v1/customers \
  -H "x-api-key: $UNITPAY_SECRET_KEY" \
  -H "content-type: application/json"
```

## Key types

| Prefix      | Name                | Use it for                                                                                             |
| ----------- | ------------------- | ------------------------------------------------------------------------------------------------------ |
| `upay_sk_…` | **Secret key**      | Server-side calls. The only key that may **track usage** and move money. Never ship it to the browser. |
| `upay_pk_…` | **Publishable key** | Safe-to-expose reads used by client SDKs. Cannot track usage or mutate billing.                        |

<Warning>
  Your secret key can charge customers and deduct credits. Keep it on your server and in environment variables — never in a client bundle, a repo, or a browser request. For customer-facing UIs, mint a short-lived portal token instead (see [React SDK](/react/introduction)).
</Warning>

## Sandbox vs live

A key is bound to **one organization and one environment** — either **sandbox** (test) or **live**. The environment is baked into the key, not the URL or a header: the same key always hits the same environment. Get one of each from the [dashboard](https://app.useunitpay.com).

<CardGroup cols={2}>
  <Card title="Sandbox" icon="flask">
    A throwaway copy of your catalog for building and testing. Use Stripe's test cards — nothing charges a real card, no real money moves. This is where [Asterix](/documentation/ai-setup) drafts your catalog.
  </Card>

  <Card title="Live" icon="rocket">
    Real customers, real cards, real invoices. Switch by swapping the key — your code doesn't change.
  </Card>
</CardGroup>

<Note>
  Because the environment lives in the key, moving from sandbox to live is a one-line change: swap `upay_sk_…` (test) for `upay_sk_…` (live). Keep them in separate environment variables so a test key never runs in production.
</Note>

## Store it in the environment

```bash .env theme={null}
UNITPAY_SECRET_KEY=upay_sk_...
```

The [Node SDK](/node/introduction) reads `UNITPAY_API_KEY` automatically if you don't pass a key explicitly:

```ts theme={null}
import { UnitPay } from '@unitpay/node';

const unitpay = new UnitPay({ apiKey: process.env.UNITPAY_SECRET_KEY });
```

## Next steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/documentation/getting-started/setup">
    Use your key to set up a catalog and run credits end to end.
  </Card>

  <Card title="AI setup" icon="wand-magic-sparkles" href="/documentation/ai-setup">
    Let Asterix build your sandbox catalog from your pricing page.
  </Card>
</CardGroup>
