# Agentes IA

> Cómo usan una zona los rastreadores y agentes IA, por categoría, bot y operador, más trampas, señales, MCP Shield y el catálogo.

Informes del Control de rastreo IA. El borde clasifica el tráfico automatizado (entrenamiento de IA, búsqueda IA, agentes IA a petición de usuarios, buscadores, automatización sin verificar, suplantaciones) y verifica los bots con el catálogo. Todas las rutas admiten cualquier rol, también tokens de zona. El comportamiento se configura en el bloque `ai_agents` de los [ajustes de borde](https://developers.openwaf.dev/es/api/edge-settings/#update-zone-edge). Consulta [AI Crawl Control](https://developers.openwaf.dev/es/ai-crawl-control/).

| Operación | Ruta |
|---|---|
| [Ver el informe de agentes IA](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-report) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/report` |
| [Ver la vista general del Control de rastreo IA](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-overview) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/overview` |
| [Ver el resumen de agentes IA](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-summary) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/summary` |
| [Ver la serie temporal de agentes IA](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-timeseries) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/timeseries` |
| [Listar los bots vistos](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-agents) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/agents` |
| [Ver las principales fuentes automatizadas](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-top) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/top` |
| [Listar eventos IA notables](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-events) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/events` |
| [Ver las métricas de agentes IA](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-metrics) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/metrics` |
| [Listar rastreadores](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-crawlers) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/crawlers` |
| [Listar quién suplanta a un bot](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-spoofers) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/spoofers` |
| [Ver la optimización para IA](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-optimization) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/optimization` |
| [Ver las señales de robots.txt](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-signals) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/signals` |
| [Ver la actividad de la trampa](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-traps) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/traps` |
| [Listar ráfagas de agentes](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-bursts) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/bursts` |
| [Ver la actividad de los endpoints IA](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-endpoints) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/endpoints` |
| [Ver la actividad de MCP Shield](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-agents-mcp) | `GET /v1/orgs/{org}/zones/{zone}/ai-agents/mcp` |
| [Ver el catálogo de bots IA](https://developers.openwaf.dev/es/api/ai-agents/#get-ai-bot-catalog) | `GET /v1/orgs/{org}/ai-agents/catalog` |

## Ver el informe de agentes IA

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/report
```

Devuelve en una llamada el resumen, la serie temporal, los bots, las principales fuentes y los ajustes `ai_agents` de la zona (o de un nombre con `host`).

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |

#### Respuesta

- `200`: Devuelve [AiReport](https://developers.openwaf.dev/es/api/schemas/#ai-report).

| Campo | Tipo | Descripción |
|---|---|---|
| `summary` | [AiSummary](https://developers.openwaf.dev/es/api/schemas/#ai-summary) |  |
| `timeseries` | [AiTimeseries](https://developers.openwaf.dev/es/api/schemas/#ai-timeseries) |  |
| `agents` | [AiAgents](https://developers.openwaf.dev/es/api/schemas/#ai-agents) |  |
| `top` | [AiTop](https://developers.openwaf.dev/es/api/schemas/#ai-top) |  |
| `settings` | [ZoneEdgeAIAgents](https://developers.openwaf.dev/es/api/schemas/#zone-edge-ai-agents) |  |
| `catalog_version` | string |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/report" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsReport({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_report(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "summary": {
    "since": "2026-10-27T09:30:00Z",
    "until": "2026-10-27T09:30:00Z",
    "prev_since": "2026-10-27T09:30:00Z",
    "prev_until": "2026-10-27T09:30:00Z",
    "requests": 128,
    "prev_requests": 128,
    "categories": [
      {
        "category": "ai_training",
        "requests": 128,
        "prev_requests": 128
      }
    ],
    "decisions": [
      {
        "decision": "example",
        "enforced": 0,
        "would": 0
      }
    ],
    "trap": {
      "injected": 0,
      "hits": 128,
      "prev_injected": 0,
      "prev_hits": 128
    }
  },
  "timeseries": {
    "step": 0,
    "points": [
      {}
    ]
  },
  "agents": {
    "rows": [
      {
        "bot_id": "948186e3-4508-48d6-a001-c683a3ec9626",
        "name": "example.com",
        "operator": "OpenAI",
        "category": "ai_training",
        "requests": 128,
        "verified": 0,
        "unverified": 0,
        "spoofed": 0,
        "methods": [
          "POST"
        ],
        "last_seen": "2026-10-27T09:30:00Z"
      }
    ]
  },
  "top": {
    "ip": [
      {
        "value": "4f1c2e9a7b3d",
        "country_code": "ES",
        "asn": 0,
        "category": "ai_training",
        "requests": 128
      }
    ],
    "fingerprint": [
      {
        "value": "4f1c2e9a7b3d",
        "country_code": "ES",
        "asn": 0,
        "category": "ai_training",
        "requests": 128
      }
    ],
    "asn": [
      {
        "value": "4f1c2e9a7b3d",
        "country_code": "ES",
        "asn": 0,
        "category": "ai_training",
        "requests": 128
      }
    ]
  },
  "settings": {
    "enabled": false,
    "mode": "log",
    "spoofed_challenge": "log",
    "template": "search_ok_block_training",
    "policy": {
      "ai_training": "allow",
      "ai_search": "allow",
      "ai_user_agent": "allow",
      "search_engine": "allow",
      "unverified_automation": "allow",
      "spoofed": "allow",
      "unverified_bot": "allow",
      "trap_hit": "allow",
      "secret_probe": "allow",
      "robots_violation": "allow",
      "agent_burst": "allow"
    },
    "bot_overrides": [
      {
        "bot_id": "948186e3-4508-48d6-a001-c683a3ec9626",
        "action": "block"
      }
    ],
    "trap": {
      "enabled": false
    },
    "tarpit": {
      "enabled": false
    },
    "robots": {
      "enabled": false,
      "content_signals": {
        "search": "yes",
        "ai_input": "yes",
        "ai_train": "yes"
      }
    },
    "markdown": {
      "enabled": false
    },
    "block_response": {
      "status": 403,
      "message": ""
    },
    "endpoints": [
      {
        "path_prefix": "/api/",
        "methods": [
          "POST"
        ],
        "max_body_bytes": 0,
        "rpm_per_ip": 0,
        "rpm_per_session": 0,
        "session_header": "X-Session-Id",
        "session_cookie": "session",
        "injection_action": "log",
        "limit_action": "log",
        "kind": "mcp",
        "mcp": {}
      }
    ]
  },
  "catalog_version": "example"
}
```

## Ver la vista general del Control de rastreo IA

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/overview
```

Devuelve la vista general del Control de rastreo IA del panel, datos destacados, tarjetas con su serie y operadores.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |

#### Respuesta

- `200`: Devuelve [AiOverview](https://developers.openwaf.dev/es/api/schemas/#ai-overview).

| Campo | Tipo | Descripción |
|---|---|---|
| `since` | string (date-time) |  |
| `until` | string (date-time) |  |
| `step` | integer |  |
| `ts` | array de string (date-time) | Fecha de la petición. |
| `facts` | object |  |
| `facts.requests` | integer | Peticiones. |
| `facts.prev_requests` | integer |  |
| `facts.status_4xx` | integer |  |
| `facts.top_operator_html` | object o null |  |
| `facts.top_path` | object o null |  |
| `facts.top_crawler` | object o null |  |
| `cards` | object |  |
| `cards.total` | [AiCard](https://developers.openwaf.dev/es/api/schemas/#ai-card) |  |
| `cards.allowed` | [AiCard](https://developers.openwaf.dev/es/api/schemas/#ai-card) |  |
| `cards.failed` | [AiCard](https://developers.openwaf.dev/es/api/schemas/#ai-card) |  |
| `operators` | array de object |  |
| `operators[].operator` | string | Empresa que opera el bot. |
| `operators[].crawlers` | array de object |  |
| `operators[].allowed` | integer |  |
| `operators[].prev_allowed` | integer |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/overview" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsOverview({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_overview(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "since": "2026-10-27T09:30:00Z",
  "until": "2026-10-27T09:30:00Z",
  "step": 0,
  "ts": [
    "2026-10-27T09:30:00Z"
  ],
  "facts": {
    "requests": 128,
    "prev_requests": 128,
    "status_4xx": 0,
    "top_operator_html": {},
    "top_path": {},
    "top_crawler": {}
  },
  "cards": {
    "total": {
      "value": 0,
      "prev": 0,
      "series": [
        0
      ]
    },
    "allowed": {
      "value": 0,
      "prev": 0,
      "series": [
        0
      ]
    },
    "failed": {
      "value": 0,
      "prev": 0,
      "series": [
        0
      ]
    }
  },
  "operators": [
    {
      "operator": "OpenAI",
      "crawlers": [
        {}
      ],
      "allowed": 0,
      "prev_allowed": 0
    }
  ]
}
```

## Ver el resumen de agentes IA

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/summary
```

Cuenta las peticiones de la zona por categoría de tráfico y decisión, más la trampa, frente al periodo anterior.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |

#### Respuesta

- `200`: Devuelve [AiSummary](https://developers.openwaf.dev/es/api/schemas/#ai-summary).

| Campo | Tipo | Descripción |
|---|---|---|
| `since` | string (date-time) |  |
| `until` | string (date-time) |  |
| `prev_since` | string (date-time) |  |
| `prev_until` | string (date-time) |  |
| `requests` | integer | Peticiones. |
| `prev_requests` | integer |  |
| `categories` | array de [AiCount](https://developers.openwaf.dev/es/api/schemas/#ai-count) |  |
| `decisions` | array de object |  |
| `decisions[].decision` | string |  |
| `decisions[].enforced` | integer |  |
| `decisions[].would` | integer | Lo que se aplicaría en modo enforce. |
| `trap` | [AiTrapSummary](https://developers.openwaf.dev/es/api/schemas/#ai-trap-summary) |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/summary" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsSummary({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_summary(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "since": "2026-10-27T09:30:00Z",
  "until": "2026-10-27T09:30:00Z",
  "prev_since": "2026-10-27T09:30:00Z",
  "prev_until": "2026-10-27T09:30:00Z",
  "requests": 128,
  "prev_requests": 128,
  "categories": [
    {
      "category": "ai_training",
      "requests": 128,
      "prev_requests": 128
    }
  ],
  "decisions": [
    {
      "decision": "example",
      "enforced": 0,
      "would": 0
    }
  ],
  "trap": {
    "injected": 0,
    "hits": 128,
    "prev_injected": 0,
    "prev_hits": 128
  }
}
```

## Ver la serie temporal de agentes IA

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/timeseries
```

Devuelve las peticiones por categoría a lo largo del tiempo.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |
| `step` | consulta | integer | No | Segundos por punto (0 = automático). Mínimo 0. |

#### Respuesta

- `200`: Devuelve [AiTimeseries](https://developers.openwaf.dev/es/api/schemas/#ai-timeseries).

| Campo | Tipo | Descripción |
|---|---|---|
| `step` | integer |  |
| `points` | array de object |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/timeseries" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsTimeseries({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_timeseries(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "step": 0,
  "points": [
    {}
  ]
}
```

## Listar los bots vistos

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/agents
```

Lista los bots vistos en la zona, verificados, sin verificar y suplantados.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |

#### Respuesta

- `200`: Devuelve [AiAgents](https://developers.openwaf.dev/es/api/schemas/#ai-agents).

| Campo | Tipo | Descripción |
|---|---|---|
| `rows` | array de [AiAgentRow](https://developers.openwaf.dev/es/api/schemas/#ai-agent-row) |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/agents" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsAgents({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_agents(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "rows": [
    {
      "bot_id": "948186e3-4508-48d6-a001-c683a3ec9626",
      "name": "example.com",
      "operator": "OpenAI",
      "category": "ai_training",
      "requests": 128,
      "verified": 0,
      "unverified": 0,
      "spoofed": 0,
      "methods": [
        "POST"
      ],
      "last_seen": "2026-10-27T09:30:00Z"
    }
  ]
}
```

## Ver las principales fuentes automatizadas

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/top
```

Devuelve las principales IP, huellas TLS y ASN del tráfico automatizado.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |
| `limit` | consulta | integer | No | Por defecto 10. Mínimo 0. |

#### Respuesta

- `200`: Devuelve [AiTop](https://developers.openwaf.dev/es/api/schemas/#ai-top).

| Campo | Tipo | Descripción |
|---|---|---|
| `ip` | array de [AiTopItem](https://developers.openwaf.dev/es/api/schemas/#ai-top-item) |  |
| `fingerprint` | array de [AiTopItem](https://developers.openwaf.dev/es/api/schemas/#ai-top-item) |  |
| `asn` | array de [AiTopItem](https://developers.openwaf.dev/es/api/schemas/#ai-top-item) | Número de sistema autónomo. |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/top" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsTop({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_top(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "ip": [
    {
      "value": "4f1c2e9a7b3d",
      "country_code": "ES",
      "asn": 0,
      "category": "ai_training",
      "requests": 128
    }
  ],
  "fingerprint": [
    {
      "value": "4f1c2e9a7b3d",
      "country_code": "ES",
      "asn": 0,
      "category": "ai_training",
      "requests": 128
    }
  ],
  "asn": [
    {
      "value": "4f1c2e9a7b3d",
      "country_code": "ES",
      "asn": 0,
      "category": "ai_training",
      "requests": 128
    }
  ]
}
```

## Listar eventos IA notables

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/events
```

Lista los eventos notables (suplantaciones, caídas en la trampa, inyecciones, detecciones de MCP Shield…), del más reciente al más antiguo.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |
| `kind` | consulta | string | No | Tipos separados por comas (spoofed, trap_hit, injection, cost_limit, automation, wba_invalid, tarpit, blocked, secret_probe, robots_violation, agent_burst; MCP Shield: mcp_blocked_method, mcp_blocked_tool, mcp_injection_request, mcp_injection_response, mcp_dlp, mcp_rate_limited, mcp_invalid). |
| `cursor` | consulta | string | No | Cursor de la página siguiente (`next_cursor` de la respuesta anterior). |
| `limit` | consulta | integer | No | Por defecto 50, máximo 500. Mínimo 0. |

#### Respuesta

- `200`: Devuelve [AiEventsPage](https://developers.openwaf.dev/es/api/schemas/#ai-events-page).

| Campo | Tipo | Descripción |
|---|---|---|
| `items` | array de [AiEvent](https://developers.openwaf.dev/es/api/schemas/#ai-event) |  |
| `next_cursor` | string |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/events?kind=spoofed,trap_hit" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsEvents({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d",
  kind: "spoofed,trap_hit"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_events(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d", kind="spoofed,trap_hit")
```



```json
{
  "items": [
    {
      "event_id": "57c7c826-7db4-42c8-af1d-3ecdfe37182f",
      "ts": "2026-10-27T09:30:00Z",
      "site_id": 0,
      "node_id": "edge-node-1",
      "host": "www.example.com",
      "kind": "spoofed",
      "category": "ai_training",
      "bot_id": "948186e3-4508-48d6-a001-c683a3ec9626",
      "verified": false,
      "verify": "",
      "decision": "example",
      "enforced": false,
      "ip": "203.0.113.10",
      "country_code": "ES",
      "asn": 0,
      "user_agent": "Mozilla/5.0",
      "tls_fingerprint": "",
      "method": "GET",
      "path": "/checkout",
      "status": 0,
      "signals": [
        "example"
      ],
      "detections": [
        {}
      ],
      "token_age_ms": 0,
      "mcp": {
        "method": "GET",
        "tool": "search_docs",
        "token_fp": "example",
        "blocked": false
      }
    }
  ],
  "next_cursor": ""
}
```

## Ver las métricas de agentes IA

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/metrics
```

Devuelve métricas por grupo (rastreador, categoría, operador, nombre o tipo de contenido) con clases de estado y páginas más pedidas. `format=csv` descarga CSV en lugar de JSON.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |
| `status` | consulta | string | No | Solo respuestas con esa clase de estado. Uno de `all`, `1xx`, `2xx`, `3xx`, `4xx`, `5xx`. |
| `group_by` | consulta | string | No | Dimensión por la que agrupar. Uno de `crawler`, `category`, `operator`, `host`, `content_type`. |
| `offset` | consulta | integer | No | Filas que saltar (paginación). Mínimo 0. |
| `limit` | consulta | integer | No | Por defecto 10, máximo 100. Mínimo 0. |
| `format` | consulta | string | No | csv: descarga CSV en lugar de JSON. Uno de `csv`. |

#### Respuesta

- `200`: Devuelve [AiMetrics](https://developers.openwaf.dev/es/api/schemas/#ai-metrics).

| Campo | Tipo | Descripción |
|---|---|---|
| `step` | integer |  |
| `ts` | array de string (date-time) | Fecha de la petición. |
| `status` | string |  |
| `group_by` | string |  |
| `cards` | object |  |
| `requests` | array de [AiSeries](https://developers.openwaf.dev/es/api/schemas/#ai-series) | Peticiones. |
| `bytes` | array de [AiSeries](https://developers.openwaf.dev/es/api/schemas/#ai-series) |  |
| `status_classes` | array de object |  |
| `content_types` | array de object |  |
| `top_paths` | [AiPathPage](https://developers.openwaf.dev/es/api/schemas/#ai-path-page) |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/metrics?group_by=operator" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsMetrics({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d",
  group_by: "operator"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_metrics(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d", group_by="operator")
```



```json
{
  "step": 0,
  "ts": [
    "2026-10-27T09:30:00Z"
  ],
  "status": "example",
  "group_by": "example",
  "cards": {},
  "requests": [
    {
      "key": "/pricing",
      "label": "AI training",
      "total": 128,
      "series": [
        0
      ]
    }
  ],
  "bytes": [
    {
      "key": "/pricing",
      "label": "AI training",
      "total": 128,
      "series": [
        0
      ]
    }
  ],
  "status_classes": [
    {}
  ],
  "content_types": [
    {}
  ],
  "top_paths": {
    "total": 128,
    "items": [
      {
        "host": "www.example.com",
        "path": "/checkout",
        "bytes": 0,
        "requests": 128,
        "secret_probe": false
      }
    ]
  }
}
```

## Listar rastreadores

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/crawlers
```

Lista los rastreadores del catálogo con sus peticiones, peticiones verificadas y suplantadas, ráfagas y acción efectiva.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |
| `inactive` | consulta | string | No | 1: incluye los bots del catálogo sin tráfico. Uno de `1`. |

#### Respuesta

- `200`: Devuelve [AiCrawlers](https://developers.openwaf.dev/es/api/schemas/#ai-crawlers).

| Campo | Tipo | Descripción |
|---|---|---|
| `step` | integer |  |
| `ts` | array de string (date-time) | Fecha de la petición. |
| `rows` | array de object |  |
| `rows[].bot_id` | string |  |
| `rows[].name` | string | Nombre. |
| `rows[].operator` | string | Empresa que opera el bot. |
| `rows[].category` | string |  |
| `rows[].methods` | array de string |  |
| `rows[].bytes` | integer |  |
| `rows[].requests` | integer | Peticiones. |
| `rows[].allowed` | integer |  |
| `rows[].unsuccessful` | integer |  |
| `rows[].series` | array de integer |  |
| `rows[].verified` | integer |  |
| `rows[].spoofed` | integer |  |
| `rows[].unverified` | integer |  |
| `rows[].bursts` | integer | Eventos agent_burst del bot. |
| `rows[].action` | string |  |
| `rows[].action_source` | string | override, category o unverified_bot. |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/crawlers" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsCrawlers({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_crawlers(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "step": 0,
  "ts": [
    "2026-10-27T09:30:00Z"
  ],
  "rows": [
    {
      "bot_id": "948186e3-4508-48d6-a001-c683a3ec9626",
      "name": "example.com",
      "operator": "OpenAI",
      "category": "ai_training",
      "methods": [
        "POST"
      ],
      "bytes": 0,
      "requests": 128,
      "allowed": 0,
      "unsuccessful": 0,
      "series": [
        0
      ],
      "verified": 0,
      "spoofed": 0,
      "unverified": 0,
      "bursts": 0,
      "action": "block",
      "action_source": "example"
    }
  ]
}
```

## Listar quién suplanta a un bot

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/spoofers
```

Lista las IP y ASN que dijeron ser un bot sin pasar su verificación. `bot` es obligatorio.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |

#### Respuesta

- `200`: Devuelve [AiSpoofers](https://developers.openwaf.dev/es/api/schemas/#ai-spoofers).

| Campo | Tipo | Descripción |
|---|---|---|
| `bot_id` | string |  |
| `ips` | array de object |  |
| `ips[].value` | string |  |
| `ips[].country_code` | string | Código de país ISO 3166-1 alfa-2. |
| `ips[].asn` | integer | Número de sistema autónomo. |
| `ips[].requests` | integer | Peticiones. |
| `ips[].last_seen` | string (date-time) |  |
| `asns` | array de object |  |
| `asns[].asn` | integer | Número de sistema autónomo. |
| `asns[].country_code` | string | Código de país ISO 3166-1 alfa-2. |
| `asns[].requests` | integer | Peticiones. |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/spoofers?bot=gptbot" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsSpoofers({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d",
  bot: "gptbot"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_spoofers(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d", bot="gptbot")
```



```json
{
  "bot_id": "948186e3-4508-48d6-a001-c683a3ec9626",
  "ips": [
    {
      "value": "4f1c2e9a7b3d",
      "country_code": "ES",
      "asn": 0,
      "requests": 128,
      "last_seen": "2026-10-27T09:30:00Z"
    }
  ],
  "asns": [
    {
      "asn": 0,
      "country_code": "ES",
      "requests": 128
    }
  ]
}
```

## Ver la optimización para IA

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/optimization
```

Devuelve las páginas que recupera la IA y la demanda de páginas que no existen. `format=csv` descarga CSV en lugar de JSON.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |
| `offset` | consulta | integer | No | Filas que saltar (paginación). Mínimo 0. |
| `limit` | consulta | integer | No | Por defecto 10, máximo 100. Mínimo 0. |
| `format` | consulta | string | No | csv: descarga CSV en lugar de JSON. Uno de `csv`. |

#### Respuesta

- `200`: Devuelve [AiOptimization](https://developers.openwaf.dev/es/api/schemas/#ai-optimization).

| Campo | Tipo | Descripción |
|---|---|---|
| `cards` | object |  |
| `cards.retrievals` | object |  |
| `cards.demand` | object |  |
| `top_pages` | [AiPathPage](https://developers.openwaf.dev/es/api/schemas/#ai-path-page) |  |
| `demand` | [AiPathPage](https://developers.openwaf.dev/es/api/schemas/#ai-path-page) |  |
| `operators` | array de object |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/optimization" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsOptimization({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_optimization(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "cards": {
    "retrievals": {
      "value": 0,
      "prev": 0
    },
    "demand": {
      "value": 0,
      "prev": 0
    }
  },
  "top_pages": {
    "total": 128,
    "items": [
      {
        "host": "www.example.com",
        "path": "/checkout",
        "bytes": 0,
        "requests": 128,
        "secret_probe": false
      }
    ]
  },
  "demand": {
    "total": 128,
    "items": [
      {
        "host": "www.example.com",
        "path": "/checkout",
        "bytes": 0,
        "requests": 128,
        "secret_probe": false
      }
    ]
  },
  "operators": [
    {}
  ]
}
```

## Ver las señales de robots.txt

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/signals
```

Devuelve las peticiones de robots.txt, los valores de Content-Signal servidos y los incumplimientos de sus reglas.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |

#### Respuesta

- `200`: Devuelve [AiSignals](https://developers.openwaf.dev/es/api/schemas/#ai-signals).

| Campo | Tipo | Descripción |
|---|---|---|
| `robots` | array de object |  |
| `robots[].host` | string |  |
| `robots[].requests` | integer | Peticiones. |
| `robots[].ok` | integer |  |
| `robots[].failed` | integer |  |
| `robots[].last_status` | integer |  |
| `robots[].content_signals` | boolean |  |
| `violations` | array de object |  |
| `violations[].bot_id` | string |  |
| `violations[].name` | string | Nombre. |
| `violations[].operator` | string | Empresa que opera el bot. |
| `violations[].category` | string |  |
| `violations[].host` | string |  |
| `violations[].path` | string |  |
| `violations[].requests` | integer | Peticiones. |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/signals" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsSignals({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_signals(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "robots": [
    {
      "host": "www.example.com",
      "requests": 128,
      "ok": 0,
      "failed": 0,
      "last_status": 0,
      "content_signals": false
    }
  ],
  "violations": [
    {
      "bot_id": "948186e3-4508-48d6-a001-c683a3ec9626",
      "name": "example.com",
      "operator": "OpenAI",
      "category": "ai_training",
      "host": "www.example.com",
      "path": "/checkout",
      "requests": 128
    }
  ]
}
```

## Ver la actividad de la trampa

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/traps
```

Devuelve las inserciones de la trampa, quién la siguió y las ráfagas de agentes.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |

#### Respuesta

- `200`: Devuelve [AiTraps](https://developers.openwaf.dev/es/api/schemas/#ai-traps).

| Campo | Tipo | Descripción |
|---|---|---|
| `injected` | integer |  |
| `hits` | integer |  |
| `prev_injected` | integer |  |
| `prev_hits` | integer |  |
| `bursts` | integer |  |
| `prev_bursts` | integer |  |
| `step` | integer |  |
| `ts` | array de string (date-time) | Fecha de la petición. |
| `series` | object |  |
| `series.injected` | array de integer |  |
| `series.hits` | array de integer |  |
| `hitters` | array de object |  |
| `hitters[].ip` | string |  |
| `hitters[].country_code` | string | Código de país ISO 3166-1 alfa-2. |
| `hitters[].asn` | integer | Número de sistema autónomo. |
| `hitters[].tls_fingerprint` | string | Huella TLS del cliente. |
| `hitters[].bot_id` | string |  |
| `hitters[].hits` | integer |  |
| `hitters[].last_seen` | string (date-time) |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/traps" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsTraps({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_traps(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "injected": 0,
  "hits": 128,
  "prev_injected": 0,
  "prev_hits": 128,
  "bursts": 0,
  "prev_bursts": 0,
  "step": 0,
  "ts": [
    "2026-10-27T09:30:00Z"
  ],
  "series": {
    "injected": [
      0
    ],
    "hits": [
      0
    ]
  },
  "hitters": [
    {
      "ip": "203.0.113.10",
      "country_code": "ES",
      "asn": 0,
      "tls_fingerprint": "",
      "bot_id": "948186e3-4508-48d6-a001-c683a3ec9626",
      "hits": 128,
      "last_seen": "2026-10-27T09:30:00Z"
    }
  ]
}
```

## Listar ráfagas de agentes

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/bursts
```

Lista las ráfagas compuestas de agentes en modo código (`agent_burst`), los clientes con su explicación, los bots y las detecciones.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |

#### Respuesta

- `200`: Devuelve [AiBursts](https://developers.openwaf.dev/es/api/schemas/#ai-bursts).

| Campo | Tipo | Descripción |
|---|---|---|
| `bursts` | integer |  |
| `prev_bursts` | integer |  |
| `clients` | array de object | Como mucho 50 elementos. |
| `clients[].ip` | string |  |
| `clients[].country_code` | string | Código de país ISO 3166-1 alfa-2. |
| `clients[].asn` | integer | Número de sistema autónomo. |
| `clients[].tls_fingerprint` | string | Huella TLS del cliente. |
| `clients[].bot_id` | string |  |
| `clients[].bursts` | integer |  |
| `clients[].last_seen` | string (date-time) |  |
| `clients[].explanations` | array de string | Etiquetas de detección (distinct_endpoints=23/10s, id_walk=…, pagination=…). Como mucho 3 elementos. |
| `crawlers` | array de object |  |
| `crawlers[].bot_id` | string |  |
| `crawlers[].name` | string | Nombre. |
| `crawlers[].operator` | string | Empresa que opera el bot. |
| `crawlers[].bursts` | integer |  |
| `detections` | array de object |  |
| `detections[].id` | string | Id. |
| `detections[].label` | string |  |
| `detections[].count` | integer |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/bursts" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsBursts({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_bursts(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "bursts": 0,
  "prev_bursts": 0,
  "clients": [
    {
      "ip": "203.0.113.10",
      "country_code": "ES",
      "asn": 0,
      "tls_fingerprint": "",
      "bot_id": "948186e3-4508-48d6-a001-c683a3ec9626",
      "bursts": 0,
      "last_seen": "2026-10-27T09:30:00Z",
      "explanations": []
    }
  ],
  "crawlers": [
    {
      "bot_id": "948186e3-4508-48d6-a001-c683a3ec9626",
      "name": "example.com",
      "operator": "OpenAI",
      "bursts": 0
    }
  ],
  "detections": [
    {
      "id": "example",
      "label": "AI training",
      "count": 128
    }
  ]
}
```

## Ver la actividad de los endpoints IA

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/endpoints
```

Devuelve la actividad de los endpoints IA del sitio, inyecciones, límites y bloqueos.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |
| `category` | consulta | string | No | Solo esa categoría de tráfico. Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`, `unverified_automation`, `spoofed`, `human`. |
| `bot` | consulta | string | No | Id de un bot del catálogo (gptbot). Como mucho 253 caracteres. |
| `operator` | consulta | string | No | Operador (OpenAI). Como mucho 64 caracteres. |

#### Respuesta

- `200`: Devuelve [AiEndpoints](https://developers.openwaf.dev/es/api/schemas/#ai-endpoints).

| Campo | Tipo | Descripción |
|---|---|---|
| `rows` | array de object |  |
| `rows[].path_prefix` | string |  |
| `rows[].requests` | integer | Peticiones. |
| `rows[].injections` | integer |  |
| `rows[].limited` | integer |  |
| `rows[].blocked` | integer |  |
| `rows[].would_block` | integer |  |
| `detections` | array de object |  |
| `detections[].id` | string | Id. |
| `detections[].label` | string |  |
| `detections[].count` | integer |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/endpoints" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsEndpoints({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_endpoints(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "rows": [
    {
      "path_prefix": "/api/",
      "requests": 128,
      "injections": 0,
      "limited": 0,
      "blocked": 0,
      "would_block": 0
    }
  ],
  "detections": [
    {
      "id": "example",
      "label": "AI training",
      "count": 128
    }
  ]
}
```

## Ver la actividad de MCP Shield

```http
GET /v1/orgs/{org}/zones/{zone}/ai-agents/mcp
```

Devuelve la actividad de MCP Shield en los endpoints MCP del sitio, mensajes JSON-RPC, bloqueos, detecciones y tools. Consulta [MCP Shield](https://developers.openwaf.dev/es/mcp-shield/).

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |
| `zone` | ruta | string (uuid) | Sí | Id de la zona (consulta [Listar zonas](https://developers.openwaf.dev/es/api/zones/#list-zones)). |
| `range` | consulta | string | No | Periodo hasta ahora: 24h (por defecto), 7d o 30d; excluyente con since. Uno de `24h`, `7d`, `30d`. |
| `since` | consulta | string (date-time) | No | RFC 3339. |
| `until` | consulta | string (date-time) | No | RFC 3339, exclusivo; por defecto ahora. Rango máximo 31 días. |
| `host` | consulta | string | No | Solo ese nombre. Como mucho 253 caracteres. |

#### Respuesta

- `200`: Devuelve [AiMcp](https://developers.openwaf.dev/es/api/schemas/#ai-mcp).

| Campo | Tipo | Descripción |
|---|---|---|
| `endpoints` | array de object |  |
| `endpoints[].path_prefix` | string |  |
| `endpoints[].requests` | integer | Peticiones. |
| `endpoints[].messages` | integer |  |
| `endpoints[].blocked` | integer |  |
| `endpoints[].detections` | integer |  |
| `endpoints[].uninspected` | integer |  |
| `tools` | array de object |  |
| `tools[].path_prefix` | string |  |
| `tools[].tool` | string |  |
| `tools[].calls` | integer |  |
| `tools[].blocked` | integer |  |
| `tools[].detections` | integer |  |
| `kinds` | array de object |  |
| `kinds[].kind` | string |  |
| `kinds[].count` | integer |  |
| `detections` | array de object |  |
| `detections[].id` | string | Id. |
| `detections[].label` | string |  |
| `detections[].count` | integer |  |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/ai-agents/mcp" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIAgentsMCP({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_agents_mcp(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "endpoints": [
    {
      "path_prefix": "/api/",
      "requests": 128,
      "messages": 0,
      "blocked": 0,
      "detections": 0,
      "uninspected": 0
    }
  ],
  "tools": [
    {
      "path_prefix": "/api/",
      "tool": "search_docs",
      "calls": 0,
      "blocked": 0,
      "detections": 0
    }
  ],
  "kinds": [
    {
      "kind": "example",
      "count": 128
    }
  ],
  "detections": [
    {
      "id": "example",
      "label": "AI training",
      "count": 128
    }
  ]
}
```

## Ver el catálogo de bots IA

```http
GET /v1/orgs/{org}/ai-agents/catalog
```

Devuelve el catálogo de bots IA con el que verifica el borde, el operador, la categoría y los métodos de verificación de cada bot (rangos de IP publicados, DNS inverso, firmas Web Bot Auth), y el estado de cada fuente oficial. No incluye los rangos ni las claves.

**Rol necesario:** `readonly` o superior.

#### Parámetros

| Nombre | En | Tipo | Obligatorio | Descripción |
|---|---|---|---|---|
| `org` | ruta | string (uuid) | Sí | Id de la organización. Cada ruta comprueba que es la del token (si no, `404`). |

#### Respuesta

- `200`: Devuelve [AiCatalog](https://developers.openwaf.dev/es/api/schemas/#ai-catalog).

| Campo | Tipo | Descripción |
|---|---|---|
| `version` | string | Número de versión. |
| `bots` | array de object |  |
| `bots[].id` | string | Id. |
| `bots[].name` | string | Nombre. |
| `bots[].operator` | string | Empresa que opera el bot. |
| `bots[].category` | string | Uno de `ai_training`, `ai_search`, `ai_user_agent`, `search_engine`. |
| `bots[].methods` | array de string | Elementos: uno de `ip`, `rdns`, `web_bot_auth`. |
| `bots[].ua` | array de string |  |
| `bots[].rdns` | array de string |  |
| `bots[].cidr_count` | integer |  |
| `bots[].signature_agents` | array de string |  |
| `sources` | array de object |  |
| `sources[].id` | string | Id. |
| `sources[].url` | string |  |
| `sources[].fetched_at` | string (date-time) o null |  |
| `sources[].ok` | boolean |  |
| `sources[].error` | string |  |
| `sources[].items` | integer |  |
| `sources[].baseline` | boolean | Sin descarga guardada: se usan los datos incluidos. |

#### Errores

| Estado | Descripción |
|---|---|
| `503` | No disponible ahora (`unavailable`); reinténtalo más tarde. |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/ai-agents/catalog" \
  -H "Authorization: Bearer $OPENWAF_TOKEN"
```

**TypeScript**


```ts
import { OpenWAF } from "./openwaf";

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.getAIBotCatalog();
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.get_ai_bot_catalog()
```



```json
{
  "version": "example",
  "bots": [
    {
      "id": "example",
      "name": "example.com",
      "operator": "OpenAI",
      "category": "ai_training",
      "methods": [
        "POST"
      ],
      "ua": [
        "example"
      ],
      "rdns": [
        "example"
      ],
      "cidr_count": 128,
      "signature_agents": [
        "example"
      ]
    }
  ],
  "sources": [
    {
      "id": "example",
      "url": "https://www.example.com/",
      "fetched_at": "2026-10-27T09:30:00Z",
      "ok": false,
      "error": "",
      "items": 0,
      "baseline": false
    }
  ]
}
```
