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

# Blockra API Authentication: API Keys, Scopes & Rate Limits

> Blockra uses secret API keys prefixed bk_ to authenticate requests. Learn how to create a key, pass it in requests, and manage scopes.

Blockra authenticates all API requests using a secret API key. You create keys in the dashboard under **Developers → API Keys**. The full key is shown only once at creation — store it securely immediately. Blockra stores only a hash of the key and cannot show it to you again.

All API keys are prefixed `bk_`.

## Creating an API key

<Steps>
  <Step title="Open the dashboard">
    Log in to [app.blockra.io](https://app.blockra.io) and navigate to **Developers → API Keys**.
  </Step>

  <Step title="Create a new key">
    Click **Create API Key**, give the key a descriptive name, and select the scopes it needs.
  </Step>

  <Step title="Copy the key">
    Copy the full key value immediately — it is shown only once. Store it in a secrets manager or environment variable.
  </Step>
</Steps>

## Sending your key

Pass the key on every request using either the `X-API-Key` header or as a Bearer token in the `Authorization` header:

<CodeGroup>
  ```bash X-API-Key header theme={null}
  curl https://api.blockra.io/payments \
    -H "X-API-Key: bk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  ```

  ```bash Authorization header theme={null}
  curl https://api.blockra.io/payments \
    -H "Authorization: Bearer bk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
  ```

  ```ts Node.js theme={null}
  const res = await fetch("https://api.blockra.io/payments", {
    headers: {
      "X-API-Key": process.env.BLOCKRA_API_KEY!,
    },
  });
  ```
</CodeGroup>

<Warning>
  API keys carry full permissions for the scopes assigned to them. Never embed a key in client-side code, mobile apps, or a public repository. All Blockra API calls must originate from your server.
</Warning>

## Scopes

Each API key is granted a set of scopes at creation. A request to an endpoint that requires a scope your key does not have returns `403` with code `HTTP_403`.

| Scope                 | What it grants                         |
| --------------------- | -------------------------------------- |
| `payments:read`       | List and retrieve payments             |
| `payments:write`      | Create payments and checkout sessions  |
| `customers:read`      | List and retrieve customers            |
| `customers:write`     | Reserved for customer write operations |
| `balance:read`        | Read account balances                  |
| `withdrawals:read`    | List withdrawal history                |
| `withdrawals:write`   | Request withdrawals                    |
| `payment_links:read`  | List payment links                     |
| `payment_links:write` | Create and update payment links        |
| `webhooks:read`       | List webhook endpoints                 |
| `webhooks:write`      | Create and delete webhook endpoints    |

<Tip>
  Follow the principle of least privilege — grant each key only the scopes it needs. Create separate keys for different services or environments.
</Tip>

## Rate limits

Requests are rate-limited per API key. If you exceed the limit, the API returns `429` with code `RATE_LIMIT_EXCEEDED`. Back off and retry after a short delay.

## Authentication errors

| HTTP status | Code                  | Cause                                       |
| ----------- | --------------------- | ------------------------------------------- |
| `401`       | `HTTP_401`            | The key is missing, malformed, or invalid   |
| `403`       | `HTTP_403`            | The key exists but lacks the required scope |
| `429`       | `RATE_LIMIT_EXCEEDED` | Too many requests from this key             |
