# Caché

> Purga lo que el borde guardó en caché de una zona, todo o por URL, prefijo, nombre o etiqueta, y sigue las purgas recientes.

Purga la caché del borde de una zona y sigue hasta dónde ha llegado cada purga. Una purga llega a los nodos del borde en un segundo aproximadamente; queda en la auditoría, no como versión de configuración.

| Operación | Ruta |
|---|---|
| [Purgar la caché](https://developers.openwaf.dev/es/api/cache/#purge-cache) | `POST /v1/orgs/{org}/zones/{zone}/cache/purge` |
| [Listar purgas](https://developers.openwaf.dev/es/api/cache/#list-cache-purges) | `GET /v1/orgs/{org}/zones/{zone}/cache/purges` |

## Purgar la caché

```http
POST /v1/orgs/{org}/zones/{zone}/cache/purge
```

Purga lo que el borde guardó en caché para la zona. El cuerpo lleva exactamente uno de `purge_everything` (`true`), `files` (URL, u objetos `{"url": …}`; se purgan todas las variantes de cada URL), `prefixes` (`nombre/ruta`), `hosts` o `tags` (valores de `Cache-Tag`), con como mucho 100 valores. Los valores se normalizan (esquema y nombre en minúsculas, sin el puerto por defecto ni el fragmento, ruta canónica) y sus nombres deben ser de la zona.

Los nodos del borde aplican la purga en un segundo aproximadamente. Una purga no es una versión de configuración: queda en la auditoría con su motivo. Por organización, 10 purgas por minuto con ráfagas de 30 para todo, nombres, prefijos y etiquetas, y 500 URL por minuto. Con `dry_run=1` solo se valida y normaliza, y no cuenta para el límite.

**Rol necesario:** `tech` o superior. También lo pueden llamar los tokens de la zona que solo purgan la caché.

**Controles de cambio:** [`dry_run`](https://developers.openwaf.dev/es/api/#configuration-changes) · [`X-Change-Reason`](https://developers.openwaf.dev/es/api/#configuration-changes) (opcional)

#### 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)). |
| `X-Change-Reason` | cabecera | string | No | Motivo del cambio (1-500 caracteres UTF-8, sin caracteres de control); por defecto, el alta de la zona. De 1 a 500 caracteres. |
| `dry_run` | consulta | string | No | `1`/`true` simula el cambio: responde 200 con el plan (`Applied`) y no guarda nada. Admite `0`/`false`; otro valor: 400. Uno de `1`, `true`, `0`, `false`. |

#### Cuerpo de la petición

Tipo de contenido `application/json`. Esquema: [PurgeRequest](https://developers.openwaf.dev/es/api/schemas/#purge-request).

Exactamente uno de los campos

| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| `purge_everything` | boolean | No |  |
| `files` | array de string o object | No | URL http(s) de la zona; se purgan todas sus variantes. Como mucho 100 elementos. |
| `files[].url` | string | Sí |  |
| `prefixes` | array de string | No | host/ruta (sin query ni fragmento). Como mucho 100 elementos. |
| `hosts` | array de string | No | Como mucho 100 elementos. |
| `tags` | array de string | No | Etiquetas de Cache-Tag (se guardan en minúsculas). Como mucho 100 elementos. |

#### Respuesta

- `200`: Purga aceptada (o simulada). Devuelve [PurgeResult](https://developers.openwaf.dev/es/api/schemas/#purge-result).

| Campo | Tipo | Descripción |
|---|---|---|
| `dry_run` | boolean | `true` en una simulación. |
| `seq` | integer | Posición de la purga (0 en una simulación). |
| `kind` | string | Uno de `everything`, `host`, `url`, `prefix`, `tag`. |
| `values` | array de string | Valores normalizados. |
| `epoch` | integer | Época nueva (everything y host). |
| `created_at` | string (date-time) | Fecha de creación. |
| `warnings` | array de string | Avisos (el cambio sigue siendo válido). |

#### Errores

| Estado | Descripción |
|---|---|
| `400` | Petición mal formada (`bad_request`). |
| `403` | El rol o los límites del token no lo permiten (`forbidden`). |
| `404` | No existe o el token no lo ve (`not_found`). |
| `409` | `zone_merged`: la zona está fusionada en otra (solo lectura hasta que se separe o se purgue). |
| `422` | Error de validación (`invalid`) o motivo ausente/no válido (`reason_required`). |
| `429` | `rate_limited`: demasiadas purgas; `Retry-After` en segundos. |

#### Ejemplo

**curl**


```sh
curl -X POST "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/cache/purge" \
  -H "Authorization: Bearer $OPENWAF_TOKEN" \
  -H "X-Change-Reason: Deploy of the new home page" \
  -H "Content-Type: application/json" \
  --data '{
    "files": [
      "https://www.example.com/index.html"
    ]
  }'
```

**TypeScript**


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

const owf = new OpenWAF({ baseUrl: "https://dash.openwaf.dev" }); // token de OPENWAF_TOKEN
const result = await owf.purgeCache({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d",
  body: {
    files: [
      "https://www.example.com/index.html"
    ]
  }
}, {
  reason: "Deploy of the new home page"
});
```

**Python**


```py
from openwaf import OpenWAF

owf = OpenWAF(base_url="https://dash.openwaf.dev")  # token de OPENWAF_TOKEN
result = owf.purge_cache(
    zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d",
    body={
        "files": [
            "https://www.example.com/index.html"
        ]
    },
    reason="Deploy of the new home page",
)
```



```json
{
  "dry_run": false,
  "seq": 0,
  "kind": "everything",
  "values": [
    "https://www.example.com/index.html"
  ],
  "epoch": 0,
  "created_at": "2026-10-27T09:30:00Z",
  "warnings": []
}
```

## Listar purgas

```http
GET /v1/orgs/{org}/zones/{zone}/cache/purges
```

Lista las purgas de los últimos 7 días, de la más reciente a la más antigua, con cuántos de los nodos activos con caché que sirven la zona (`nodes`) han aplicado ya cada una (`applied`).

**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)). |
| `limit` | consulta | integer | No | Número máximo de elementos. Por defecto `20`. De 1 a 100. |

#### Respuesta

- `200`: Devuelve `items`, un array de [PurgeStatus](https://developers.openwaf.dev/es/api/schemas/#purge-status).

| Campo | Tipo | Descripción |
|---|---|---|
| `items[].seq` | integer |  |
| `items[].zone_id` | string (uuid) | Id de la zona. |
| `items[].kind` | string | Uno de `everything`, `host`, `url`, `prefix`, `tag`. |
| `items[].values` | array de string |  |
| `items[].actor` | string | Quién hizo el cambio: un token, un usuario u OpenWAF. |
| `items[].created_at` | string (date-time) | Fecha de creación. |
| `items[].nodes` | integer | Nodos activos con caché que sirven la zona. |
| `items[].applied` | integer | Cuántos de ellos ya la han recibido. |

#### Errores

| Estado | Descripción |
|---|---|
| `404` | No existe o el token no lo ve (`not_found`). |

#### Ejemplo

**curl**


```sh
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/cache/purges" \
  -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.listCachePurges({
  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.list_cache_purges(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "items": [
    {
      "seq": 0,
      "zone_id": "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d",
      "kind": "everything",
      "values": [
        "https://www.example.com/index.html"
      ],
      "actor": "token:11111111-2222-4333-8444-555555555555",
      "created_at": "2026-10-27T09:30:00Z",
      "nodes": 0,
      "applied": 0
    }
  ]
}
```
