# Protect your AI endpoints

> Inspect requests to your own chat and completion APIs for prompt injection and exfiltration, cap their bodies and limit them per IP or per session.

`ai_agents.endpoints` protects up to 20 of your own AI endpoints, such as `/api/chat`. For each request to an endpoint path, the edge reads the body (and forwards it intact), runs 27 deterministic detectors in English and Spanish, checks the spend parameters and applies per-IP and per-session limits. For MCP servers, use [MCP Shield](https://developers.openwaf.dev/mcp-shield/) instead.

## What is detected

- **Injection**: instruction overrides, system prompt extraction, jailbreak personas ("DAN", "developer mode"), fake system or compliance notices, chat template tokens (`<|im_start|>`), runs of zero-width characters, HTML comments with orders, base64 that decodes to orders and exfiltration patterns (`curl … | sh`, `env | grep KEY`).
- **Cost limits** (denial of wallet): more than 65,536 output tokens (`max_tokens` and equivalents), more than 8 completions (`n`, `best_of`…), more than 1,000 messages or more than 128 tools.

Each detection is recorded as `{id, label, snippet}`, with a snippet of at most 160 bytes of the request, shown as plain text in the dashboard and the CLI.

## Endpoint fields

| Field | Rules |
|---|---|
| `path_prefix` | Starts with `/`, at most 256 bytes, unique. |
| `methods` | Any of `POST`, `PUT`, `PATCH`, `GET`. |
| `max_body_bytes` | 1–1,048,576. A larger body is a limit violation. |
| `rpm_per_ip` | Requests per minute per IP; `0` = no limit; at most 100,000. |
| `rpm_per_session` | Requests per minute per session; `0` = no limit; at most 100,000. |
| `session_header` / `session_cookie` | Where the session value comes from. |
| `injection_action` | `log` or `block`. |
| `limit_action` | `log` or `block`, for rate, size and cost limits. |

## Answers in enforce mode

| Violation | Answer |
|---|---|
| Over `rpm_per_ip` or `rpm_per_session` | `429` `{"error":"rate limit exceeded"}` with `Retry-After` |
| Body over `max_body_bytes` | `413` `{"error":"request body too large"}` |
| Injection detected | `403` `{"error":"request rejected"}` |
| Cost limit exceeded | `400` `{"error":"request exceeds cost limits"}` |

In `log` mode, or with the action `log`, the request continues and an `injection` or `cost_limit` event is recorded.

## Add an endpoint

**Dashboard**

**AI Crawl Control → AI endpoints**.
**CLI**

```sh
openwaf-cloud ctl zones set example.com ai_agents.endpoints:='[{"path_prefix":"/api/chat","methods":["POST"],
  "max_body_bytes":32768,"rpm_per_ip":30,"rpm_per_session":0,"session_header":"","session_cookie":"",
  "injection_action":"block","limit_action":"log"}]' --reason "Protect the chat API"
```
**API**

`PATCH …/edge` with `{"ai_agents": {"endpoints": [...]}}`; the list is replaced whole.
**MCP**

`ai_agents_settings` with `"patch": {"endpoints": [...]}`.


The **AI endpoints** report (`--view endpoints`) shows injections, limits, blocks and detections per endpoint.
