---
title: "Authentication and API keys"
description: "Send your store's API key with every request. The API key decides live or sandbox mode and which endpoints you can call."
---

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

# Authentication and API keys

This page explains how to send your API key, the two kinds of API keys, and what happens when authentication fails.

## Send your API key with every request

Every request MUST send one store API key in the `Authorization` header. Write `Bearer`, a space, and then the API key. This format is called a bearer token:

```http
GET /api/b2b/v1/products HTTP/1.1
Host: cardzone.ai
Authorization: Bearer cz_your_api_key
```

An API key belongs to exactly one store. It can only see and create that store's orders. It can never reach another store's records.

## Live and sandbox API keys

- A **sandbox** API key is for testing. It returns fixed responses and spends no money.
- A **live** API key places real orders and spends real money from your store wallet.

There is one base URL for both. The API key you send decides how the server behaves, so your code never switches hosts.

| | Sandbox API key | Live API key |
| --- | --- | --- |
| When you get it | Right away, from **Developers** in the dashboard | After business verification is approved |
| Catalog | Five static scenario products | Your store's real catalog and prices |
| Orders | Static responses, nothing is created | Real orders, store wallet charges, and fulfillment |
| Webhooks | Never sent | Sent to your endpoints |
| Store wallet requirement | Never applies | Applies, see [store wallet](https://docs.cardzone.ai/concepts/wallet/) |
| Cancel order | `403` | Available |

> **Keep live API keys on your server**
>
> An API key can spend money from your store wallet.
>
> - You MUST keep it in a secrets manager and call the API only from your backend (your server).
> - NEVER put it in browser code or mobile app code.
> - If an API key leaks, click **Rotate** in the dashboard. The old API key stops working immediately.

## Permissions

Each API key has permissions. A permission decides which endpoints (API URLs) the API key can call. API keys you create in the dashboard get every permission below. Cardzone support can create API keys with fewer permissions if you ask.

| Permission | Endpoints |
| --- | --- |
| `catalog:read` | [List categories](https://docs.cardzone.ai/reference/categories/list/), [List products](https://docs.cardzone.ai/reference/products/list/) |
| `orders:create` | [Create order](https://docs.cardzone.ai/reference/orders/create/), [Cancel order](https://docs.cardzone.ai/reference/orders/cancel/), [Look up player profile](https://docs.cardzone.ai/reference/player-profiles/create/) |
| `orders:read` | [Poll order status](https://docs.cardzone.ai/reference/orders/retrieve/) |
| `wallet:read` | [Get balance](https://docs.cardzone.ai/reference/balance/retrieve/) |

If a valid API key doesn't have the permission it needs, you get `403 forbidden`.

## What a failed authentication looks like

You get `401` with the standard [error shape](https://docs.cardzone.ai/resources/errors/) when:

- the API key is missing, revoked, or unknown.
- the store of a live API key is inactive.
- the store of a live API key doesn't have approved business verification yet, or the primary user's email isn't verified yet.

Every case returns `code: "unauthorized"` with the same message. So if a live API key used to work and now fails, check these things in the dashboard.

The example below starts with **No key** ticked. It shows the response to a request without an API key. Untick **No key** to see the response with an API key:

## Language

Send `Accept-Language: ar` to get Arabic text. You get Arabic labels for recipient fields. Where Cardzone has them, you also get Arabic product names and error messages.

Field keys, statuses, and error codes never change with the language. Your code MUST make decisions based on those values, never on the text. The **AR** toggle on any example shows the Arabic response.

Source: https://docs.cardzone.ai/concepts/authentication/index.mdx
