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

# Blink PDF API Authentication: Keys, Headers & Errors

> Learn how to obtain your Blink PDF API key, pass it securely in request headers, and handle common errors like 401 and 402.

Every render or template request to the Blink PDF **REST API** must include an API key. REST uses **API key authentication** — you pass your key in the `x-api-key` header on authenticated requests. There are no sessions or cookies on the REST surface.

The [MCP server](/mcp/overview) accepts the same `bp_*` keys (as `Authorization: Bearer` or `x-api-key`) and also supports **OAuth 2.1 + PKCE** for remote agent connectors — see [Connect a Client](/mcp/setup).

## Get your API key

API keys are created and managed in the [Blink PDF dashboard](https://app.blinkpdf.io).

<Steps>
  <Step title="Log in to your dashboard">
    Go to [app.blinkpdf.io](https://app.blinkpdf.io) and sign in. If you don't have an account yet, sign up for free — no credit card required.
  </Step>

  <Step title="Open the API Keys section">
    From the dashboard sidebar, click **API Keys**. Any keys you've already created are listed here (the secret portion is masked after creation).
  </Step>

  <Step title="Create a new key">
    Click **Create new key**, give it a descriptive name (for example, `production-invoices` or `staging-test`), and confirm. Your full API key is displayed **once** — copy it now.
  </Step>
</Steps>

<Warning>
  **Never share or expose your API key.** Treat it like a password. If you accidentally commit a key to a public repository or expose it in client-side code, rotate it immediately from the dashboard — your old key will stop working the moment you do.
</Warning>

## Pass your key in requests

Include your API key in the `x-api-key` header of every render or template request:

```http theme={null}
x-api-key: bp_...
```

Here's a complete example:

```bash curl theme={null}
curl https://api.blinkpdf.io/v1/render \
  --request POST \
  --header 'Accept: application/pdf' \
  --header 'Content-Type: application/json' \
  --header 'x-api-key: bp_xxxxxxxxxxxxxxxxxxxx' \
  --data '{"markdown": "# Hello\n\nWorld"}'
```

### Key format

API keys always start with the prefix `bp_` followed by a unique alphanumeric string. If your key doesn't start with `bp_`, double-check that you copied the full key from the dashboard.

| Prefix | Environment |
| ------ | ----------- |
| `bp_`  | Production  |

<Info>
  All keys are scoped to your account and inherit your plan's rate limits and monthly render quota.
</Info>

## Use environment variables

Never hardcode your API key in source files. Store it in an environment variable and read it at runtime. This prevents accidental exposure through version control, logs, or error messages.

### Set the environment variable

```bash theme={null}
export BLINKPDF_API_KEY="bp_xxxxxxxxxxxxxxxxxxxx"
```

For persistent configuration, add this line to your shell profile (`.bashrc`, `.zshrc`) or use a secrets manager like AWS Secrets Manager, HashiCorp Vault, or your CI/CD platform's secret store.

### Read it in your code

<CodeGroup>
  ```python Python theme={null}
  import os
  import requests

  api_key = os.environ["BLINKPDF_API_KEY"]  # Raises KeyError if not set

  response = requests.post(
      "https://api.blinkpdf.io/v1/render",
      headers={
          "x-api-key": api_key,
          "Accept": "application/pdf",
          "Content-Type": "application/json",
      },
      json={"markdown": "# Hello, world!"},
  )

  response.raise_for_status()
  ```

  ```javascript Node.js theme={null}
  const apiKey = process.env.BLINKPDF_API_KEY;

  if (!apiKey) {
    throw new Error("BLINKPDF_API_KEY environment variable is not set");
  }

  const response = await fetch("https://api.blinkpdf.io/v1/render", {
    method: "POST",
    headers: {
      "x-api-key": apiKey,
      Accept: "application/pdf",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ markdown: "# Hello, world!" }),
  });

  if (!response.ok) {
    throw new Error(`${response.status} ${response.statusText}`);
  }
  ```

  ```bash curl theme={null}
  # Read the key from the environment rather than pasting it inline
  curl https://api.blinkpdf.io/v1/render \
    --request POST \
    --header 'Accept: application/pdf' \
    --header 'Content-Type: application/json' \
    --header "x-api-key: ${BLINKPDF_API_KEY}" \
    --data '{"markdown": "# Hello\n\nWorld"}'
  ```
</CodeGroup>

## Common authentication errors

### 401 Unauthorized

You'll receive a `401` response if the `x-api-key` header is missing, malformed, or contains an invalid key.

```http theme={null}
HTTP/1.1 401 Unauthorized
```

**Common causes and fixes:**

| Cause                              | Fix                                                                             |
| ---------------------------------- | ------------------------------------------------------------------------------- |
| Header not included in the request | Add `x-api-key: bp_...` to every authenticated render or template request       |
| Key was rotated or deleted         | Create a new key in the dashboard and update your configuration                 |
| Key copied with extra whitespace   | Trim leading/trailing spaces from the key string                                |
| Key sent in the wrong header       | Send the key in `x-api-key` — Blink PDF does not use the `Authorization` header |

### 402 Payment Required

A `402` response means your API key is valid, but your plan's spend cap has been reached. Usage beyond the included volume is paused until the next billing period. The response body is `{ "error": "spend_cap_reached", "detail": "..." }`.

```http theme={null}
HTTP/1.1 402 Payment Required
```

**Common causes and fixes:**

| Cause                            | Fix                                                                                                                       |
| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| Spend cap reached for the period | Raise the spend cap or upgrade your plan in the [dashboard](https://app.blinkpdf.io), or wait for the next billing period |
| Included volume exhausted        | Review your current plan limits and usage in the [dashboard](https://app.blinkpdf.io)                                     |

<Tip>
  You can monitor your remaining quota and usage at any time from the **Usage** section of your [dashboard](https://app.blinkpdf.io).
</Tip>

## Security best practices

* **Rotate keys regularly.** Create a new key and retire the old one on a schedule, or any time team membership changes.
* **Use one key per environment.** Maintain separate keys for development, staging, and production so you can rotate or revoke them independently.
* **Use one key per service.** If multiple services call the Blink PDF API, give each its own key. This limits the blast radius if one key is compromised.
* **Never log the key.** Avoid printing the full `x-api-key` header in application logs or error messages.
* **Restrict access at the infrastructure level.** Where possible, use a secrets manager or environment injection rather than `.env` files checked into source control.

## Next steps

<CardGroup cols={2}>
  <Card title="Quickstart" icon="rocket" href="/quickstart">
    If you haven't made your first API call yet, start here.
  </Card>

  <Card title="API Reference" icon="code" href="/api-reference/overview">
    Explore all parameters and headers for the `POST /v1/render` endpoint.
  </Card>
</CardGroup>
