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

# Authentication

> Authenticate requests to the Mage Loyalty API using API keys.

## API keys

All API requests must include your API key in the `Authorization` header. No `Bearer` prefix is needed.

```bash theme={null}
curl https://api.mageloyalty.com/v1/customers \
  -H "Authorization: your-api-key-here"
```

<Warning>
  API keys grant access to your loyalty program data. Never expose full-access keys in client-side code.
</Warning>

## Create an API key

<Steps>
  <Step title="Open API key settings">
    In the Mage Loyalty dashboard, go to **Settings > API Keys**. API keys are available on the Growth plan and above.
  </Step>

  <Step title="Generate a key">
    Give the key a name so you can recognize where it is used, choose **Full access** or **Read-only** (see [Scopes](#scopes)), and generate it.
  </Step>

  <Step title="Copy it once">
    The key is shown only once, at creation. Copy it and store it somewhere secure. If you lose it, revoke the key and generate a new one.
  </Step>
</Steps>

You can revoke a key at any time from the same screen, which immediately stops it from authenticating. Revoked keys can then be deleted.

## Scopes

Each API key has one of two access levels:

| Scope           | Description                               |
| --------------- | ----------------------------------------- |
| **Full access** | Can perform all read and write operations |
| **Read only**   | Can only perform `GET` requests           |

Use **read-only keys** if you do not wish to manipulate any loyalty data via the API.

Attempting a write operation with a read-only key returns `403 Forbidden`:

```json theme={null}
{
  "errors": [
    {
      "status": "403",
      "title": "Forbidden",
      "detail": "This API key is read-only and cannot perform write operations"
    }
  ]
}
```

## Missing or invalid key

Requests without an `Authorization` header, or with a key that is unknown or has been revoked, return `401 Unauthorized`. A request made with an invalid key looks like this:

<RequestExample>
  ```bash cURL theme={null}
  curl https://api.mageloyalty.com/v1/customers \
    -H "Authorization: revoked-or-unknown-key"
  ```

  ```javascript Node theme={null}
  const response = await fetch("https://api.mageloyalty.com/v1/customers", {
    headers: {
      Authorization: "revoked-or-unknown-key",
    },
  });

  const data = await response.json();
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.mageloyalty.com/v1/customers",
      headers={"Authorization": "revoked-or-unknown-key"},
  )

  data = response.json()
  ```

  ```php PHP theme={null}
  <?php
  $ch = curl_init("https://api.mageloyalty.com/v1/customers");
  curl_setopt_array($ch, [
      CURLOPT_RETURNTRANSFER => true,
      CURLOPT_HTTPHEADER => [
          "Authorization: revoked-or-unknown-key",
      ],
  ]);
  $data = json_decode(curl_exec($ch), true);
  ```
</RequestExample>

<ResponseExample>
  ```json 401 Missing header theme={null}
  {
    "errors": [
      {
        "status": "401",
        "title": "Unauthorized",
        "detail": "Missing Authorization header"
      }
    ]
  }
  ```

  ```json 401 Invalid key theme={null}
  {
    "errors": [
      {
        "status": "401",
        "title": "Unauthorized",
        "detail": "Invalid or revoked API key"
      }
    ]
  }
  ```

  ```json 403 Read-only key theme={null}
  {
    "errors": [
      {
        "status": "403",
        "title": "Forbidden",
        "detail": "This API key is read-only and cannot perform write operations"
      }
    ]
  }
  ```
</ResponseExample>
