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

# Authentication

> Authenticate your requests with a API key.

# Authentication

Every request to the API is authenticated with a API key in the `x-api-key` header.

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

There is no OAuth, JWT or sessions: it is simple authentication by API key, intended for server-to-server calls from your backend or from an agent, not to be exposed directly in a public web client.

## Example

```bash theme={null}
curl -X POST "https://api.markpdf.tech/convert/raw?filename=report.pdf" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "content-type: application/pdf" \
  --data-binary "@report.pdf"
```

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

headers = {"x-api-key": "YOUR_API_KEY", "content-type": "application/pdf"}
r = httpx.post(
    "https://api.markpdf.tech/convert/raw",
    params={"filename": "report.pdf"},
    headers=headers,
    content=open("report.pdf", "rb").read(),
)
```

```javascript theme={null}
const res = await fetch("https://api.markpdf.tech/convert/raw?filename=report.pdf", {
  method: "POST",
  headers: { "x-api-key": "YOUR_API_KEY", "content-type": "application/pdf" },
  body: fileBuffer,
});
```

## Where does the key go on each endpoint

The `x-api-key` header is the same on all endpoints (`/convert`, `/convert/raw`, `/convert/from-url`, `/pdf/index`, `GET /jobs/{id}`). The key is not accepted as a query param or inside the JSON body: it always goes in the header.

## Good practices

* Save the API key in an environment variable or secrets manager, never in the code or in the repository.
* Do not include it in URLs or logs (query params are usually registered in proxies and CDNs).
* Use a different key per environment (development, staging, production) to be able to revoke one without affecting the others.
* If a key leaks (for example in a log, a public repository or a frontend client), rotate it immediately.
* If your application calls API from the browser, do not expose the key directly: proxy the request from your own backend.

## Authentication errors

| Situation                                                         | Status | What to review                                                          |
| ----------------------------------------------------------------- | ------ | ----------------------------------------------------------------------- |
| Missing `x-api-key` header                                        | `401`  | Add the header to each request.                                         |
| Invavalid or unknown API key                                      | `401`  | Verify that you copied the complete key, without spaces or line breaks. |
| Vavalid key without permission for the requested resource or host | `403`  | Check the source `url` and the scope of your key.                       |

<Warning>
  A request without vavalid `x-api-key` responds `401`.
</Warning>

<Tip>
  If you integrate the API into an AI agent (for example with function calling), do not give the API key to the model as free text at the prompt: inject it into the code that executes the HTTP call, outside the context of the LLM.
</Tip>

## Frequently asked questions

* **Does the API key expire?** It depends on your plan; consult the panel where you generated it. Rotating it manually is the recommended way to invavalidate it early.
* **Can I have several active keys at the same time?** Yes, it is the recommended way to separate different environments or applications.
* **What happens if I send the `x-api-key` header twice?** Only one value is evaluated; avoid this by configuring the HTTP client correctly.
