# Rendimiento real (RUM)

> Core Web Vitals medidos en los navegadores de tus visitantes, LCP, INP, CLS, FCP y TTFB, por página, país, dispositivo y más.

La monitorización de usuarios reales (RUM) mide las Core Web Vitals en los navegadores de los visitantes. Viene desactivada; se activa en los [ajustes de borde](https://developers.openwaf.dev/es/api/edge-settings/#update-zone-edge) de la zona (`rum`). Todas las rutas comparten los mismos filtros y usan el percentil 75 (p75).

| Operación | Ruta |
|---|---|
| [Ver el resumen RUM](https://developers.openwaf.dev/es/api/rum/#get-rum-summary) | `GET /v1/orgs/{org}/zones/{zone}/rum/summary` |
| [Ver la serie temporal RUM](https://developers.openwaf.dev/es/api/rum/#get-rum-timeseries) | `GET /v1/orgs/{org}/zones/{zone}/rum/timeseries` |
| [Ver el desglose RUM](https://developers.openwaf.dev/es/api/rum/#get-rum-breakdown) | `GET /v1/orgs/{org}/zones/{zone}/rum/breakdown` |
| [Ver las partes del LCP](https://developers.openwaf.dev/es/api/rum/#get-rum-lcp-parts) | `GET /v1/orgs/{org}/zones/{zone}/rum/lcp-parts` |
| [Ver los culpables RUM](https://developers.openwaf.dev/es/api/rum/#get-rum-offenders) | `GET /v1/orgs/{org}/zones/{zone}/rum/offenders` |
| [Ver el informe RUM](https://developers.openwaf.dev/es/api/rum/#get-rum-report) | `GET /v1/orgs/{org}/zones/{zone}/rum/report` |

## Ver el resumen RUM

```http
GET /v1/orgs/{org}/zones/{zone}/rum/summary
```

Devuelve el p75 de LCP, INP, CLS, FCP y TTFB con su valoración, frente al periodo anterior de la misma duración, y lo que hizo el borde con el script de medida (`injection`). Los percentiles son por vista de página; las visitas se estiman a partir de la tasa de muestreo.

**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)). |
| `since` | consulta | string (date-time) | No | RFC 3339; por defecto until - 7 días. |
| `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. |
| `path` | consulta | string | No | Solo esa ruta exacta. Como mucho 512 caracteres. Patrón `^/`. |
| `country` | consulta | string | No | ISO 3166-1 alfa-2 (se admite en minúsculas). Patrón `^[A-Za-z]{2}$`. |
| `node` | consulta | string | No | Solo las vistas medidas a través de ese nodo. Como mucho 128 caracteres. |
| `device` | consulta | string | No | Solo ese tipo de dispositivo. Uno de `mobile`, `tablet`, `desktop`. |
| `connection` | consulta | string | No | Solo ese tipo de conexión efectiva. Uno de `4g`, `3g`, `2g`, `slow-2g`. |
| `nav_type` | consulta | string | No | Solo ese tipo de navegación. Uno de `navigate`, `reload`, `back-forward`, `back-forward-cache`, `prerender`, `restore`. |

#### Respuesta

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

| Campo | Tipo | Descripción |
|---|---|---|
| `since` | string (date-time) |  |
| `until` | string (date-time) |  |
| `prev_since` | string (date-time) |  |
| `prev_until` | string (date-time) |  |
| `visits` | number | Vistas de página estimadas: Σ 1/sample_rate, redondeado. |
| `prev_visits` | number |  |
| `metrics` | object |  |
| `metrics.lcp` | [RumSummaryAgg](https://developers.openwaf.dev/es/api/schemas/#rum-summary-agg) |  |
| `metrics.inp` | [RumSummaryAgg](https://developers.openwaf.dev/es/api/schemas/#rum-summary-agg) |  |
| `metrics.cls` | [RumSummaryAgg](https://developers.openwaf.dev/es/api/schemas/#rum-summary-agg) |  |
| `metrics.fcp` | [RumSummaryAgg](https://developers.openwaf.dev/es/api/schemas/#rum-summary-agg) |  |
| `metrics.ttfb` | [RumSummaryAgg](https://developers.openwaf.dev/es/api/schemas/#rum-summary-agg) |  |
| `injection` | object |  |
| `injection.injected` | integer |  |
| `injection.csp_nonce` | integer |  |
| `injection.csp_blocked` | integer |  |
| `injection.no_head` | integer |  |
| `injection.sampled_out` | 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/rum/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.getRumSummary({
  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_rum_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",
  "visits": 128.0,
  "prev_visits": 128.0,
  "metrics": {
    "lcp": {
      "p50": 0.5,
      "p75": 0.5,
      "p90": 0.5,
      "count": 128,
      "good": 0,
      "needs_improvement": 0,
      "poor": 0,
      "prev_p75": 0.5,
      "prev_count": 128
    },
    "inp": {
      "p50": 0.5,
      "p75": 0.5,
      "p90": 0.5,
      "count": 128,
      "good": 0,
      "needs_improvement": 0,
      "poor": 0,
      "prev_p75": 0.5,
      "prev_count": 128
    },
    "cls": {
      "p50": 0.5,
      "p75": 0.5,
      "p90": 0.5,
      "count": 128,
      "good": 0,
      "needs_improvement": 0,
      "poor": 0,
      "prev_p75": 0.5,
      "prev_count": 128
    },
    "fcp": {
      "p50": 0.5,
      "p75": 0.5,
      "p90": 0.5,
      "count": 128,
      "good": 0,
      "needs_improvement": 0,
      "poor": 0,
      "prev_p75": 0.5,
      "prev_count": 128
    },
    "ttfb": {
      "p50": 0.5,
      "p75": 0.5,
      "p90": 0.5,
      "count": 128,
      "good": 0,
      "needs_improvement": 0,
      "poor": 0,
      "prev_p75": 0.5,
      "prev_count": 128
    }
  },
  "injection": {
    "injected": 0,
    "csp_nonce": 0,
    "csp_blocked": 0,
    "no_head": 0,
    "sampled_out": 0
  }
}
```

## Ver la serie temporal RUM

```http
GET /v1/orgs/{org}/zones/{zone}/rum/timeseries
```

Devuelve el p75 de cada métrica y las visitas por intervalo, también los intervalos vacíos (con `null` y `0`).

**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)). |
| `since` | consulta | string (date-time) | No | RFC 3339; por defecto until - 7 días. |
| `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. |
| `path` | consulta | string | No | Solo esa ruta exacta. Como mucho 512 caracteres. Patrón `^/`. |
| `country` | consulta | string | No | ISO 3166-1 alfa-2 (se admite en minúsculas). Patrón `^[A-Za-z]{2}$`. |
| `node` | consulta | string | No | Solo las vistas medidas a través de ese nodo. Como mucho 128 caracteres. |
| `device` | consulta | string | No | Solo ese tipo de dispositivo. Uno de `mobile`, `tablet`, `desktop`. |
| `connection` | consulta | string | No | Solo ese tipo de conexión efectiva. Uno de `4g`, `3g`, `2g`, `slow-2g`. |
| `nav_type` | consulta | string | No | Solo ese tipo de navegación. Uno de `navigate`, `reload`, `back-forward`, `back-forward-cache`, `prerender`, `restore`. |
| `step` | consulta | integer | No | Segundos por punto, múltiplo de 60, como mucho 1000 puntos. Por defecto el menor de 300, 900, 1800, 3600, 10800, 21600, 43200 y 86400 que da como mucho 60 puntos. Cubos alineados con la época Unix (UTC). Mínimo 60. |

#### Respuesta

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

| Campo | Tipo | Descripción |
|---|---|---|
| `step` | integer |  |
| `points` | array de object |  |
| `points[].ts` | string (date-time) | Fecha de la petición. |
| `points[].visits` | number |  |
| `points[].lcp` | number o null | p75. |
| `points[].inp` | number o null |  |
| `points[].cls` | number o null |  |
| `points[].fcp` | number o null |  |
| `points[].ttfb` | number o null |  |

#### 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/rum/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.getRumTimeseries({
  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_rum_timeseries(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "step": 0,
  "points": [
    {
      "ts": "2026-10-27T09:30:00Z",
      "visits": 128.0,
      "lcp": 0.5,
      "inp": 0.5,
      "cls": 0.5,
      "fcp": 0.5,
      "ttfb": 0.5
    }
  ]
}
```

## Ver el desglose RUM

```http
GET /v1/orgs/{org}/zones/{zone}/rum/breakdown
```

Devuelve las métricas por valor de una dimensión (`by`), ordenadas por visitas (los empates, por clave).

**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)). |
| `since` | consulta | string (date-time) | No | RFC 3339; por defecto until - 7 días. |
| `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. |
| `path` | consulta | string | No | Solo esa ruta exacta. Como mucho 512 caracteres. Patrón `^/`. |
| `country` | consulta | string | No | ISO 3166-1 alfa-2 (se admite en minúsculas). Patrón `^[A-Za-z]{2}$`. |
| `node` | consulta | string | No | Solo las vistas medidas a través de ese nodo. Como mucho 128 caracteres. |
| `device` | consulta | string | No | Solo ese tipo de dispositivo. Uno de `mobile`, `tablet`, `desktop`. |
| `connection` | consulta | string | No | Solo ese tipo de conexión efectiva. Uno de `4g`, `3g`, `2g`, `slow-2g`. |
| `nav_type` | consulta | string | No | Solo ese tipo de navegación. Uno de `navigate`, `reload`, `back-forward`, `back-forward-cache`, `prerender`, `restore`. |
| `by` | consulta | string | No | Dimensión por la que agrupar. Uno de `path`, `country`, `node`, `device`, `connection`, `nav_type`, `host`, `viewport`. Por defecto `path`. |
| `limit` | consulta | integer | No | Número máximo de elementos. Por defecto `10`. De 1 a 100. |

#### Respuesta

- `200`: Devuelve [RumBreakdown](https://developers.openwaf.dev/es/api/schemas/#rum-breakdown).

| Campo | Tipo | Descripción |
|---|---|---|
| `by` | string |  |
| `rows` | array de object |  |
| `rows[].key` | string | Valor de la dimensión ("" = desconocido). |
| `rows[].visits` | number |  |
| `rows[].metrics` | [RumMetrics](https://developers.openwaf.dev/es/api/schemas/#rum-metrics) |  |

#### 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/rum/breakdown?by=country" \
  -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.getRumBreakdown({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d",
  by: "country"
});
```

**Python**


```py
from openwaf import OpenWAF

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



```json
{
  "by": "path",
  "rows": [
    {
      "key": "/pricing",
      "visits": 128.0,
      "metrics": {
        "lcp": {},
        "inp": {},
        "cls": {},
        "fcp": {},
        "ttfb": {}
      }
    }
  ]
}
```

## Ver las partes del LCP

```http
GET /v1/orgs/{org}/zones/{zone}/rum/lcp-parts
```

Divide el LCP en sus partes (TTFB, espera y descarga del recurso y retardo de pintado) para las vistas lentas (LCP igual o superior al p75) y para todas. `by` añade `rows` con los 10 dispositivos o rutas con más vistas.

**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)). |
| `since` | consulta | string (date-time) | No | RFC 3339; por defecto until - 7 días. |
| `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. |
| `path` | consulta | string | No | Solo esa ruta exacta. Como mucho 512 caracteres. Patrón `^/`. |
| `country` | consulta | string | No | ISO 3166-1 alfa-2 (se admite en minúsculas). Patrón `^[A-Za-z]{2}$`. |
| `node` | consulta | string | No | Solo las vistas medidas a través de ese nodo. Como mucho 128 caracteres. |
| `device` | consulta | string | No | Solo ese tipo de dispositivo. Uno de `mobile`, `tablet`, `desktop`. |
| `connection` | consulta | string | No | Solo ese tipo de conexión efectiva. Uno de `4g`, `3g`, `2g`, `slow-2g`. |
| `nav_type` | consulta | string | No | Solo ese tipo de navegación. Uno de `navigate`, `reload`, `back-forward`, `back-forward-cache`, `prerender`, `restore`. |
| `by` | consulta | string | No | Añade `rows` (10 con más vistas). Uno de `device`, `path`. |

#### Respuesta

- `200`: Devuelve [RumLcpParts](https://developers.openwaf.dev/es/api/schemas/#rum-lcp-parts).

| Campo | Tipo | Descripción |
|---|---|---|
| `lcp_p75` | number o null |  |
| `count` | integer |  |
| `parts` | [RumLcpPartsValues](https://developers.openwaf.dev/es/api/schemas/#rum-lcp-parts-values) | Vistas con LCP ≥ p75. |
| `all` | [RumLcpPartsValues](https://developers.openwaf.dev/es/api/schemas/#rum-lcp-parts-values) |  |
| `rows` | array de object |  |
| `rows[].key` | string |  |
| `rows[].lcp_p75` | number o null |  |
| `rows[].count` | integer |  |
| `rows[].parts` | [RumLcpPartsValues](https://developers.openwaf.dev/es/api/schemas/#rum-lcp-parts-values) |  |

#### 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/rum/lcp-parts" \
  -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.getRumLcpParts({
  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_rum_lcp_parts(zone="6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d")
```



```json
{
  "lcp_p75": 0.5,
  "count": 128,
  "parts": {
    "ttfb": 0.5,
    "load_delay": 0.5,
    "load_duration": 0.5,
    "render_delay": 0.5
  },
  "all": {
    "ttfb": 0.5,
    "load_delay": 0.5,
    "load_duration": 0.5,
    "render_delay": 0.5
  },
  "rows": [
    {
      "key": "/pricing",
      "lcp_p75": 0.5,
      "count": 128,
      "parts": {
        "ttfb": 0.5,
        "load_delay": 0.5,
        "load_duration": 0.5,
        "render_delay": 0.5
      }
    }
  ]
}
```

## Ver los culpables RUM

```http
GET /v1/orgs/{org}/zones/{zone}/rum/offenders
```

Clasifica los elementos, recursos y scripts con más vistas malas de su métrica (y luego con más vistas), sin la clave vacía. Las claves (selectores, URL) vienen de las páginas de los visitantes.

**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)). |
| `since` | consulta | string (date-time) | No | RFC 3339; por defecto until - 7 días. |
| `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. |
| `path` | consulta | string | No | Solo esa ruta exacta. Como mucho 512 caracteres. Patrón `^/`. |
| `country` | consulta | string | No | ISO 3166-1 alfa-2 (se admite en minúsculas). Patrón `^[A-Za-z]{2}$`. |
| `node` | consulta | string | No | Solo las vistas medidas a través de ese nodo. Como mucho 128 caracteres. |
| `device` | consulta | string | No | Solo ese tipo de dispositivo. Uno de `mobile`, `tablet`, `desktop`. |
| `connection` | consulta | string | No | Solo ese tipo de conexión efectiva. Uno de `4g`, `3g`, `2g`, `slow-2g`. |
| `nav_type` | consulta | string | No | Solo ese tipo de navegación. Uno de `navigate`, `reload`, `back-forward`, `back-forward-cache`, `prerender`, `restore`. |
| `kind` | consulta | string | Sí | Qué clasificar. Uno de `lcp_element`, `lcp_url`, `inp_target`, `inp_script`, `cls_target`. |
| `limit` | consulta | integer | No | Número máximo de elementos. Por defecto `10`. De 1 a 100. |

#### Respuesta

- `200`: Devuelve un objeto con los campos de abajo.

| Campo | Tipo | Descripción |
|---|---|---|
| `kind` | string |  |
| `rows` | array de [RumOffender](https://developers.openwaf.dev/es/api/schemas/#rum-offender) |  |

#### 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/rum/offenders?kind=lcp_element" \
  -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.getRumOffenders({
  zone: "6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d",
  kind: "lcp_element"
});
```

**Python**


```py
from openwaf import OpenWAF

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



```json
{
  "kind": "example",
  "rows": [
    {
      "key": "/pricing",
      "count": 128,
      "p75": 0.5,
      "poor": 0,
      "top_path": "/docs/"
    }
  ]
}
```

## Ver el informe RUM

```http
GET /v1/orgs/{org}/zones/{zone}/rum/report
```

Devuelve en una llamada todo lo que muestra la página de rendimiento real del panel, con los ajustes RUM de la zona, el resumen, una serie temporal con paso automático, desgloses por ruta (25 filas), país, nodo, dispositivo y conexión (10 filas), las partes del LCP por dispositivo y los principales culpables. `breakdowns.device` no aplica el filtro `device`.

**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)). |
| `since` | consulta | string (date-time) | No | RFC 3339; por defecto until - 7 días. |
| `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. |
| `path` | consulta | string | No | Solo esa ruta exacta. Como mucho 512 caracteres. Patrón `^/`. |
| `country` | consulta | string | No | ISO 3166-1 alfa-2 (se admite en minúsculas). Patrón `^[A-Za-z]{2}$`. |
| `node` | consulta | string | No | Solo las vistas medidas a través de ese nodo. Como mucho 128 caracteres. |
| `device` | consulta | string | No | Solo ese tipo de dispositivo. Uno de `mobile`, `tablet`, `desktop`. |
| `connection` | consulta | string | No | Solo ese tipo de conexión efectiva. Uno de `4g`, `3g`, `2g`, `slow-2g`. |
| `nav_type` | consulta | string | No | Solo ese tipo de navegación. Uno de `navigate`, `reload`, `back-forward`, `back-forward-cache`, `prerender`, `restore`. |

#### Respuesta

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

| Campo | Tipo | Descripción |
|---|---|---|
| `summary` | [RumSummary](https://developers.openwaf.dev/es/api/schemas/#rum-summary) |  |
| `timeseries` | [RumTimeseries](https://developers.openwaf.dev/es/api/schemas/#rum-timeseries) |  |
| `breakdowns` | object |  |
| `breakdowns.path` | [RumBreakdown](https://developers.openwaf.dev/es/api/schemas/#rum-breakdown) |  |
| `breakdowns.country` | [RumBreakdown](https://developers.openwaf.dev/es/api/schemas/#rum-breakdown) |  |
| `breakdowns.node` | [RumBreakdown](https://developers.openwaf.dev/es/api/schemas/#rum-breakdown) |  |
| `breakdowns.device` | [RumBreakdown](https://developers.openwaf.dev/es/api/schemas/#rum-breakdown) |  |
| `breakdowns.connection` | [RumBreakdown](https://developers.openwaf.dev/es/api/schemas/#rum-breakdown) |  |
| `lcp_parts` | [RumLcpParts](https://developers.openwaf.dev/es/api/schemas/#rum-lcp-parts) |  |
| `offenders` | object |  |
| `offenders.lcp_element` | array de [RumOffender](https://developers.openwaf.dev/es/api/schemas/#rum-offender) |  |
| `offenders.inp_target` | array de [RumOffender](https://developers.openwaf.dev/es/api/schemas/#rum-offender) |  |
| `offenders.inp_script` | array de [RumOffender](https://developers.openwaf.dev/es/api/schemas/#rum-offender) |  |
| `offenders.cls_target` | array de [RumOffender](https://developers.openwaf.dev/es/api/schemas/#rum-offender) |  |
| `settings` | [ZoneEdgeRUM](https://developers.openwaf.dev/es/api/schemas/#zone-edge-rum) |  |

#### 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/rum/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.getRumReport({
  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_rum_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",
    "visits": 128.0,
    "prev_visits": 128.0,
    "metrics": {
      "lcp": {
        "p50": 0.5,
        "p75": 0.5,
        "p90": 0.5,
        "count": 128,
        "good": 0,
        "needs_improvement": 0,
        "poor": 0,
        "prev_p75": 0.5,
        "prev_count": 128
      },
      "inp": {
        "p50": 0.5,
        "p75": 0.5,
        "p90": 0.5,
        "count": 128,
        "good": 0,
        "needs_improvement": 0,
        "poor": 0,
        "prev_p75": 0.5,
        "prev_count": 128
      },
      "cls": {
        "p50": 0.5,
        "p75": 0.5,
        "p90": 0.5,
        "count": 128,
        "good": 0,
        "needs_improvement": 0,
        "poor": 0,
        "prev_p75": 0.5,
        "prev_count": 128
      },
      "fcp": {
        "p50": 0.5,
        "p75": 0.5,
        "p90": 0.5,
        "count": 128,
        "good": 0,
        "needs_improvement": 0,
        "poor": 0,
        "prev_p75": 0.5,
        "prev_count": 128
      },
      "ttfb": {
        "p50": 0.5,
        "p75": 0.5,
        "p90": 0.5,
        "count": 128,
        "good": 0,
        "needs_improvement": 0,
        "poor": 0,
        "prev_p75": 0.5,
        "prev_count": 128
      }
    },
    "injection": {
      "injected": 0,
      "csp_nonce": 0,
      "csp_blocked": 0,
      "no_head": 0,
      "sampled_out": 0
    }
  },
  "timeseries": {
    "step": 0,
    "points": [
      {
        "ts": "2026-10-27T09:30:00Z",
        "visits": 128.0,
        "lcp": 0.5,
        "inp": 0.5,
        "cls": 0.5,
        "fcp": 0.5,
        "ttfb": 0.5
      }
    ]
  },
  "breakdowns": {
    "path": {
      "by": "path",
      "rows": [
        {}
      ]
    },
    "country": {
      "by": "path",
      "rows": [
        {}
      ]
    },
    "node": {
      "by": "path",
      "rows": [
        {}
      ]
    },
    "device": {
      "by": "path",
      "rows": [
        {}
      ]
    },
    "connection": {
      "by": "path",
      "rows": [
        {}
      ]
    }
  },
  "lcp_parts": {
    "lcp_p75": 0.5,
    "count": 128,
    "parts": {
      "ttfb": 0.5,
      "load_delay": 0.5,
      "load_duration": 0.5,
      "render_delay": 0.5
    },
    "all": {
      "ttfb": 0.5,
      "load_delay": 0.5,
      "load_duration": 0.5,
      "render_delay": 0.5
    },
    "rows": [
      {
        "key": "/pricing",
        "lcp_p75": 0.5,
        "count": 128,
        "parts": {}
      }
    ]
  },
  "offenders": {
    "lcp_element": [
      {
        "key": "/pricing",
        "count": 128,
        "p75": 0.5,
        "poor": 0,
        "top_path": "/docs/"
      }
    ],
    "inp_target": [
      {
        "key": "/pricing",
        "count": 128,
        "p75": 0.5,
        "poor": 0,
        "top_path": "/docs/"
      }
    ],
    "inp_script": [
      {
        "key": "/pricing",
        "count": 128,
        "p75": 0.5,
        "poor": 0,
        "top_path": "/docs/"
      }
    ],
    "cls_target": [
      {
        "key": "/pricing",
        "count": 128,
        "p75": 0.5,
        "poor": 0,
        "top_path": "/docs/"
      }
    ]
  },
  "settings": {
    "enabled": false,
    "sample_rate": 1,
    "exclude_paths": []
  }
}
```
