> ## Documentation Index
> Fetch the complete documentation index at: https://docs.vertracloud.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Rendimiento de la aplicación

> Devuelve los tiempos de borde y de contenedor del sitio, de p50 a p99.9, por país y ubicación de borde, más las rutas lentas. Pro y superiores.

Devuelve cuánto tardan las peticiones, en dos relojes: la **borde** es todo el tiempo que esperó el visitante el primer byte, y el **contenedor** es la parte que tardó tu aplicación en responder. Cada uno trae el promedio y los percentiles p50, p75, p90, p95, p99 y p99.9. La respuesta también trae los tiempos por país y por ubicación de borde, las rutas más lentas y la salud de las rutas más pedidas. Son los datos de [Rendimiento](https://docs.vertracloud.app/es-es/web-analytics/performance.md) y **requiere un plan con los detalles de rendimiento (Pro y superiores)**.

**id** `string` *required*

El ID de la aplicación. Si pertenece a un workspace, pasa su ID en el query parameter `workspace_id`.

**workspace\_id** `string`

Si la aplicación pertenece a un workspace, el ID del workspace. Obligatorio para miembros del workspace que actúan sobre una aplicación que no es suya.

**start** `string`

Inicio de la ventana (ISO 8601). Por defecto: 24 horas antes de `end`.

**end** `string`

Fin de la ventana (ISO 8601). Por defecto: ahora. No puede estar en el futuro.

**compare** `boolean` (default: false)

Envía también el período anterior, de la misma duración y justo antes de la ventana, en `previous`. Por defecto `false`.

**compare\_start** `string`

Inicio del periodo a comparar (ISO 8601). El periodo comparado tiene la misma duración que la ventana (`end` menos `start`) y empieza aquí; `previous.start` y `previous.end` en la respuesta muestran cuál fue. Implica `compare=true` y no se puede enviar con `compare=false`. Sin él, `compare=true` compara con el periodo justo antes de la ventana.

**limit** `integer` (default: 10)

Entradas en `countries`, `edge_locations`, `slow_paths` y `path_issues`, de 1 a 25. Por defecto 10.

La ventana dura como máximo 30 días y no puede empezar antes del historial del plan (7 o 30 días, ver [Planes y límites](https://docs.vertracloud.app/es-es/plans-and-limits.md)).

### Filtros

Cada dimensión de abajo también es un filtro, y todos se pueden combinar: cada uno restringe todas las partes de la respuesta. Cada filtro recibe **un valor**, exactamente como aparece en una entrada de breakdown o en una petición del registro, así que un valor leído en una respuesta se puede reenviar sin cambios. Envía `(none)` para quedarte solo con las peticiones que no tienen nada en la dimensión.

**country** `string`

País del visitante, ISO 3166-1 alfa-2 (`BR`).

**edge\_location** `string`

Código IATA de la ubicación de borde que respondió (`GRU`).

**host** `string`

Hostname que pidió el visitante: el subdominio de la aplicación o uno de sus dominios. Solo se aceptan hosts de la aplicación.

**path** `string`

Ruta de la petición, sin la query string. Es un prefijo: `/api` coincide con `/api`, `/api/users` y `/apix`.

**method** `string`

Método HTTP (`GET`, `POST`...).

**status** `string`

Estado HTTP que recibió el visitante (`404`), o una clase: `2xx`, `3xx`, `4xx` o `5xx`.

**protocol** `string`

Versión de HTTP: `HTTP/1.1`, `HTTP/2` o `HTTP/3`.

**device** `string`

Tipo de dispositivo: `desktop`, `mobile` o `tablet`.

**os** `string`

Sistema operativo del visitante (`Windows`, `iOS`...).

**browser** `string`

Navegador del visitante (`Chrome`, `Safari`...).

**referer** `string`

Host de la página que llevó a la petición (`google.com`). `(none)` es una visita directa, sin referer.

**asn** `string`

Número del sistema autónomo de la red del visitante (`28573`).

**ip** `string`

Dirección IP del visitante.

**content\_type** `string`

Tipo de contenido respondido (`html`, `json`, `css`, `js`, `png`...).

**cache\_status** `string`

Si la borde respondió desde su caché: `hit`, `miss`, `dynamic`, `bypass`, `expired`, `revalidated`...

**bot** `string`

Categoría de un bot verificado (`Search Engine Crawler`...). `(none)` es un visitante que no es un bot verificado.

### Respuesta

**response** `object`

**Toggle object**

**start** `string`

Inicio de la ventana realmente leída (ISO 8601). Puede estar redondeado respecto al que enviaste.

**end** `string`

Fin de la ventana realmente leída (ISO 8601).

**hosts** `string[]`

Hostnames que se leyeron: el subdominio de la aplicación y sus dominios activos.

**web\_published** `boolean`

`false` cuando la aplicación no tiene sitio publicado. La respuesta es entonces un estado vacío, no un error: `hosts` viene vacío y los datos también.

**sampled** `boolean`

`true` cuando el tráfico es lo bastante alto como para que los números se estimen a partir de una muestra.

**stale** `boolean`

`true` cuando no se pudieron leer los datos más recientes y esta es una respuesta anterior. Ver `generated_at`.

**generated\_at** `string`

Cuándo se leyeron los datos (ISO 8601).

**history\_days** `integer`

Cuántos días hacia atrás puede leer el plan del dueño de la aplicación.

**interval** `string`

Tamaño de cada punto de `series`: `1m`, `5m`, `15m` o `1h`. La API lo elige según la duración de la ventana: cuanto más corta, más finos los puntos.

**summary** `object | null`

Tiempos de la ventana. `null` cuando no hubo peticiones en la ventana. `container` viene `null` cuando ninguna petición llegó a la aplicación (todas las respondió la caché).

**series** `object[]`

Puntos de la serie temporal; `time` es el inicio de cada punto, con `requests` y los tiempos `edge` y `container` (`avg_ms`, `p50_ms`, `p95_ms`, `p99_ms`). `container` viene `null` en un punto sin peticiones que llegaran a la aplicación.

**previous** `object | null`

El período anterior, solo con `compare=true`; si no, `null`. Tiene `start`, `end`, un `summary` (`null` cuando no hubo peticiones en él) y una `series` con el mismo `interval` y el mismo número de puntos que la actual, en el mismo orden.

**countries** `object[]`

Tiempos por país del visitante, mayor `requests` primero. Cada entrada tiene `value` (envíalo como el filtro `country`), `label`, `requests`, `edge` y `container`.

**edge\_locations** `object[]`

Tiempos por ubicación de borde, mayor `requests` primero. Misma entrada que `countries`.

**slow\_paths** `object[]`

Rutas más lentas por el percentil 95 del tiempo de borde, la más lenta primero. Las rutas con muy pocas peticiones se omiten. Misma entrada que `countries`; `value` es la ruta.

**path\_issues** `object[]`

Las rutas más pedidas con su salud, mayor `requests` primero. Cada entrada tiene `path` (envíalo como el filtro `path`), `requests`, `errors` (5xx), `error_rate` (0 a 1), `avg_ms` y `p99_ms` del tiempo de borde.

Campos de `summary.edge` y `summary.container`, todos en milisegundos:

**avg\_ms** `number`

Tiempo promedio.

**p50\_ms** `number`

Mediana: la mitad de las peticiones fue más rápida.

**p75\_ms** `number`

Percentil 75.

**p90\_ms** `number`

Percentil 90.

**p95\_ms** `number`

Percentil 95.

**p99\_ms** `number`

Percentil 99.

**p999\_ms** `number`

Percentil 99,9.

```json Response theme={null}
{
  "response": {
    "start": "2026-11-02T18:00:00Z",
    "end": "2026-11-03T18:00:00Z",
    "hosts": [
      "my-app.vertraweb.app",
      "www.example.com"
    ],
    "web_published": true,
    "sampled": false,
    "stale": false,
    "generated_at": "2026-11-03T18:01:12Z",
    "history_days": 7,
    "interval": "1h",
    "summary": {
      "requests": 18420,
      "edge": {
        "avg_ms": 188,
        "p50_ms": 96,
        "p75_ms": 170,
        "p90_ms": 310,
        "p95_ms": 412,
        "p99_ms": 880,
        "p999_ms": 2100
      },
      "container": {
        "avg_ms": 141,
        "p50_ms": 70,
        "p75_ms": 128,
        "p90_ms": 240,
        "p95_ms": 330,
        "p99_ms": 720,
        "p999_ms": 1800
      }
    },
    "series": [
      {
        "time": "2026-11-02T18:00:00Z",
        "requests": 702,
        "edge": {
          "avg_ms": 180,
          "p50_ms": 92,
          "p95_ms": 400,
          "p99_ms": 860
        },
        "container": {
          "avg_ms": 135,
          "p50_ms": 66,
          "p95_ms": 320,
          "p99_ms": 700
        }
      },
      {
        "time": "2026-11-02T19:00:00Z",
        "requests": 731,
        "edge": {
          "avg_ms": 195,
          "p50_ms": 101,
          "p95_ms": 430,
          "p99_ms": 910
        },
        "container": null
      }
    ],
    "previous": null,
    "countries": [
      {
        "value": "BR",
        "label": null,
        "requests": 14210,
        "edge": {
          "avg_ms": 160,
          "p50_ms": 88,
          "p95_ms": 350,
          "p99_ms": 760
        },
        "container": {
          "avg_ms": 120,
          "p50_ms": 60,
          "p95_ms": 280,
          "p99_ms": 620
        }
      },
      {
        "value": "US",
        "label": null,
        "requests": 2105,
        "edge": {
          "avg_ms": 310,
          "p50_ms": 170,
          "p95_ms": 640,
          "p99_ms": 1300
        },
        "container": {
          "avg_ms": 130,
          "p50_ms": 64,
          "p95_ms": 300,
          "p99_ms": 650
        }
      }
    ],
    "edge_locations": [
      {
        "value": "GRU",
        "label": null,
        "requests": 11800,
        "edge": {
          "avg_ms": 150,
          "p50_ms": 85,
          "p95_ms": 330,
          "p99_ms": 700
        },
        "container": {
          "avg_ms": 118,
          "p50_ms": 58,
          "p95_ms": 270,
          "p99_ms": 600
        }
      }
    ],
    "slow_paths": [
      {
        "value": "/api/report",
        "label": null,
        "requests": 210,
        "edge": {
          "avg_ms": 1210,
          "p50_ms": 980,
          "p95_ms": 2600,
          "p99_ms": 4100
        },
        "container": {
          "avg_ms": 1180,
          "p50_ms": 950,
          "p95_ms": 2540,
          "p99_ms": 4020
        }
      }
    ],
    "path_issues": [
      {
        "path": "/api/checkout",
        "requests": 412,
        "errors": 6,
        "error_rate": 0.0146,
        "avg_ms": 402,
        "p99_ms": 1900
      }
    ]
  }
}
```

```bash cURL theme={null}
curl -G "https://api.vertracloud.app/v1/apps/app-abc123def456/analytics/performance" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  --data-urlencode "start=2026-11-02T18:00:00Z" \
  --data-urlencode "end=2026-11-03T18:00:00Z" \
  --data-urlencode "country=BR" \
  --data-urlencode "limit=5"
```

### Notas

* Requiere el scope `apps:read` cuando se llama con una API key. Los miembros de un workspace necesitan permiso para leer la aplicación.
* **Pro y superiores.** En Starter la llamada falla con `PLAN_DOES_NOT_SUPPORT_WEB_ANALYTICS_PERFORMANCE`. El flag del plan es `features.web_analytics_performance` en [Listar planes](https://docs.vertracloud.app/es-es/api-reference/endpoint/plans/list.md). El número único de velocidad p95 de todos los planes está en `summary.edge_time_p95_ms` de [Tráfico de la aplicación](https://docs.vertracloud.app/es-es/api-reference/endpoint/apps/analytics/traffic.md).
* **Muestreo.** Con tráfico alto los números se estiman a partir de una muestra y `sampled` viene `true`. Ver [Muestreo y retraso](https://docs.vertracloud.app/es-es/web-analytics/sampling-and-delay.md).
* **Retraso.** Los datos se actualizan cada unos 5 minutos, así que las peticiones más nuevas pueden tardar unos minutos en aparecer. Si los datos más recientes no se pueden leer ahora, puede volver una respuesta anterior con `stale: true` (revisa `generated_at`); de lo contrario, la llamada falla con `ANALYTICS_BUSY`.
* **Privacidad.** Vertra Cloud no guarda nada de los visitantes; guarda solo totales por app (recuentos, visitas, bytes, tasas de error y tiempos de respuesta) hasta 31 días, borrados con la app. No se guarda ninguna IP, ruta, query string ni user agent. `ip` y `query` vuelven sin máscara; enmascararlos es decisión del cliente que los muestra. Ver [Privacidad](https://docs.vertracloud.app/es-es/web-analytics/privacy.md).

### Respuestas de error

| Status | Código | Cuándo |
| - | - | - |
| 401 | `AUTH_TOKEN_MISSING` / `API_KEY_INVALID` / `SESSION_REVOKED` | Falta el header `Authorization`, la API key es inválida o la sesión del panel fue revocada. |
| 403 | `API_KEY_IP_DENIED` / `API_KEY_SCOPE_DENIED` | La API key se usa desde una IP fuera de su lista permitida, o no tiene el scope `apps:read`. |
| 403 | `ACCESS_DENIED` | La aplicación pertenece a otra cuenta, o no tienes el permiso de workspace para leerla. |
| 403 | `PLAN_REQUIRED` | La cuenta no tiene plan activo. |
| 403 | `PLAN_DOES_NOT_SUPPORT_WEB_ANALYTICS_PERFORMANCE` | El plan no incluye los detalles de rendimiento (Starter). Pasa a Pro o superior. |
| 404 | `APP_NOT_FOUND` | La aplicación no existe. |
| 400 | `VALIDATION_ERROR` | Un parámetro falló la validación, como `limit` fuera de rango, un `cursor` inválido o una fecha `start`/`end` mal formada; `details.path` nombra el campo. También cuando `compare_start` está mal formado o se envía con `compare=false`. |
| 400 | `INVALID_RANGE` | `start` es posterior a `end`, `end` está en el futuro o la ventana supera los 30 días. También cuando el periodo que empieza en `compare_start` termina después de `start`, lo que solaparía la ventana. |
| 400 | `ANALYTICS_RANGE_EXCEEDS_PLAN` | `start` es anterior a lo que el plan puede leer. `details.history_days` trae el límite en días y `details.earliest` el `start` más antiguo aceptado ahora. También cuando `compare_start` es anterior a lo que el plan puede leer. |
| 429 | `RATE_LIMIT_EXCEEDED` | Demasiadas consultas seguidas. `details.retry_after` indica la espera en segundos; la cabecera `Retry-After` viene siempre con ella. |
| 503 | `ANALYTICS_BUSY` | Momento de alta demanda y sin respuesta reciente disponible para la consulta. Espera `details.retry_after` segundos e inténtalo de nuevo. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.