---
title: "API Protection"
manual: "LLMs.txt Generator"
version: "1.0"
permalink: "https://docs.typo3.org/permalink/rtfirst/llms-txt:api-protection@1.0"
source: "ApiProtection.rst"
rendered: "2026-09-28T14:13:24+00:00"
---

# API Protection {#api-protection}

You can protect both `/llms.txt` and the `.md` suffix endpoints with
an API key. This is useful when you want to:

-   Restrict access to your own chatbots or RAG systems
-   Prevent external scraping of structured content
-   Control who can access your LLM-optimized content

## Setting Up API Protection {#api-protection-setup}

1.  Go to **Site Management > Settings** in the TYPO3 Backend.
1.  Find the **LLMs-Text** category.
1.  Enter your API key in the **API Key for Format Access** field.
1.  Save and clear all caches.

> [!TIP]
> Generate a secure API key with:
>
> ```bash
> php -r "echo bin2hex(random_bytes(32)) . PHP_EOL;"
> ```
>
> Or in DDEV:
>
> ```bash
> ddev exec php -r "echo bin2hex(random_bytes(32)) . PHP_EOL;"
> ```

## Authenticating Requests {#api-protection-usage}

Pass the API key via **HTTP header** (recommended):

```bash
# Access llms.txt
curl -H "X-LLM-API-Key: your-secret-key" https://example.com/llms.txt

# Access page as Markdown
curl -H "X-LLM-API-Key: your-secret-key" https://example.com/about.md
```

Or via **query parameter**:

```text
https://example.com/llms.txt?api_key=your-secret-key
https://example.com/about.md?api_key=your-secret-key
```

> [!WARNING]
> Using query parameters exposes the API key in server logs and browser
> history. Prefer the HTTP header method for production use.

## Error Response {#api-protection-error}

Invalid or missing API key returns **HTTP 401 Unauthorized** with a JSON body:

```json
{
  "error": "Unauthorized",
  "message": "Valid API key required. Provide via X-LLM-API-Key header or api_key query parameter."
}
```

## Integration Examples {#api-protection-integrations}

### n8n Integration {#n8n-integration}

In n8n HTTP Request node, add the header:

| Name | Value |
| --- | --- |
| `X-LLM-API-Key` | `your-secret-key` |

### Python Integration {#python-integration}

```python
import requests

headers = {
    "X-LLM-API-Key": "your-secret-key"
}

# Get llms.txt
response = requests.get("https://example.com/llms.txt", headers=headers)
print(response.text)

# Get page as Markdown
response = requests.get("https://example.com/about.md", headers=headers)
print(response.text)
```

### JavaScript/Node.js Integration {#javascript-node-js-integration}

```javascript
const response = await fetch("https://example.com/llms.txt", {
  headers: {
    "X-LLM-API-Key": "your-secret-key"
  }
});

const content = await response.text();
console.log(content);
```

### cURL Integration {#curl-integration}

```bash
# Store API key in environment variable
export LLM_API_KEY="your-secret-key"

# Access llms.txt
curl -H "X-LLM-API-Key: $LLM_API_KEY" https://example.com/llms.txt

# Access multiple pages
for page in about services contact; do
  curl -H "X-LLM-API-Key: $LLM_API_KEY" "https://example.com/${page}.md" > "${page}.md"
done
```

## Behavior When Enabled {#api-protection-behavior}

When API key protection is enabled:

1.  **llms.txt** requires authentication
1.  **All .md endpoints** require authentication
1.  The **HTML header link** (`<link rel="alternate">`) is automatically hidden
1.  The llms.txt file includes **authentication instructions**

## Disabling API Protection {#api-protection-disable}

To make endpoints publicly accessible again:

1.  Go to **Site Management > Settings**
1.  Clear the **API Key for Format Access** field
1.  Save and clear all caches

The header link will automatically reappear and endpoints will be publicly
accessible.
