> ## 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.

# Tráfego da aplicação

> Retorna o tráfego do site de uma aplicação: totais, série no tempo e breakdowns por país, rota e dispositivo, com filtros e comparação de períodos.

Retorna o tráfego do site de uma aplicação: totais, uma série no tempo e os valores mais frequentes de cada dimensão (países, rotas, dispositivos, navegadores, referers...). Todo filtro vale para todas as partes da resposta, então uma chamada dá os números por trás de um clique na sub-aba Tráfego. São os mesmos dados de [Tráfego e filtros](https://docs.vertracloud.app/pt-br/web-analytics/traffic.md), do [Resumo](https://docs.vertracloud.app/pt-br/web-analytics/summary.md) e de [Comparar](https://docs.vertracloud.app/pt-br/web-analytics/compare.md).

**id** `string` *required*

O ID da aplicação. Se ela pertencer a um workspace, informe o ID dele no query parameter `workspace_id`.

**workspace\_id** `string`

Se a aplicação pertencer a um workspace, o ID do workspace. Obrigatório para membros do workspace que agem sobre uma aplicação que não lhes pertence.

**start** `string`

Início da janela (ISO 8601). Padrão: 24 horas antes de `end`.

**end** `string`

Fim da janela (ISO 8601). Padrão: agora. Não pode estar no futuro.

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

Envia também o período anterior, do mesmo tamanho e logo antes da janela, em `previous`. Padrão `false`.

**compare\_start** `string`

Início do período a comparar (ISO 8601). O período comparado tem o mesmo tamanho da janela (`end` menos `start`) e começa aqui; `previous.start` e `previous.end` na resposta mostram qual foi. Implica `compare=true` e não pode ser enviado com `compare=false`. Sem ele, `compare=true` compara com o período logo antes da janela.

**breakdowns** `string`

Dimensões separadas por vírgula para detalhar, como `country,path`. Omitido: todos os recortes. Vazio (`breakdowns=`): nenhum, só o resumo e a série, com resposta mais rápida. Nome desconhecido: `VALIDATION_ERROR`. As dimensões estão listadas em Filtros.

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

Entradas por breakdown, de 1 a 25. Padrão 10.

A janela tem no máximo 30 dias e não pode começar antes do histórico do plano (7 ou 30 dias, veja [Planos e limites](https://docs.vertracloud.app/pt-br/plans-and-limits.md)).

### Filtros

Cada dimensão abaixo também é um filtro, e todos podem ser combinados: cada um restringe todas as partes da resposta. Cada filtro recebe **um valor**, exatamente como aparece numa entrada de breakdown ou numa requisição do log, então um valor lido numa resposta pode ser enviado de volta sem mudar. Envie `(none)` para manter só as requisições que não têm nada na dimensão.

**country** `string`

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

**edge\_location** `string`

Código IATA da localização de borda que respondeu (`GRU`).

**host** `string`

Hostname que o visitante pediu: o subdomínio da aplicação ou um dos seus domínios. Só são aceitos hosts da aplicação.

**path** `string`

Caminho da requisição, sem a query string. É um prefixo: `/api` casa com `/api`, `/api/users` e `/apix`.

**method** `string`

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

**status** `string`

Status HTTP que o visitante recebeu (`404`), ou uma classe: `2xx`, `3xx`, `4xx` ou `5xx`.

**protocol** `string`

Versão do HTTP: `HTTP/1.1`, `HTTP/2` ou `HTTP/3`.

**device** `string`

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

**os** `string`

Sistema operacional do visitante (`Windows`, `iOS`...).

**browser** `string`

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

**referer** `string`

Host da página que levou à requisição (`google.com`). `(none)` é uma visita direta, sem referer.

**asn** `string`

Número do sistema autônomo da rede do visitante (`28573`).

**ip** `string`

Endereço IP do visitante.

**content\_type** `string`

Tipo de conteúdo respondido (`html`, `json`, `css`, `js`, `png`...).

**cache\_status** `string`

Se a borda respondeu do cache: `hit`, `miss`, `dynamic`, `bypass`, `expired`, `revalidated`...

**bot** `string`

Categoria de um bot verificado (`Search Engine Crawler`...). `(none)` é um visitante que não é um bot verificado.

### Resposta

**response** `object`

**Toggle object**

**start** `string`

Início da janela realmente lida (ISO 8601). Pode ser arredondado em relação ao que você enviou.

**end** `string`

Fim da janela realmente lida (ISO 8601).

**hosts** `string[]`

Hostnames que foram lidos: o subdomínio da aplicação e seus domínios ativos.

**web\_published** `boolean`

`false` quando a aplicação não tem site publicado. A resposta é então um estado vazio, não um erro: `hosts` vem vazio e os dados também.

**sampled** `boolean`

`true` quando o tráfego é alto o bastante para que os números sejam estimados a partir de uma amostra.

**stale** `boolean`

`true` quando os dados mais recentes não puderam ser lidos e esta é uma resposta anterior. Veja `generated_at`.

**generated\_at** `string`

Quando os dados foram lidos (ISO 8601).

**history\_days** `integer`

Quantos dias para trás o plano do dono da aplicação consegue ler.

**interval** `string`

Tamanho de cada ponto de `series`: `1m`, `5m`, `15m` ou `1h`. A API escolhe pelo tamanho da janela: quanto menor a janela, mais finos os pontos.

**summary** `object | null`

Totais da janela. `null` quando não houve requisição na janela.

**series** `object[]`

Pontos da série no tempo; `time` é o início de cada ponto.

**previous** `object | null`

O período anterior, só com `compare=true`; caso contrário `null`. Tem `start`, `end`, um `summary` (`null` quando não houve requisição nele) e uma `series` com o mesmo `interval` e o mesmo número de pontos da atual, na mesma ordem.

**breakdowns** `object`

Entradas mais frequentes de cada dimensão, maior `requests` primeiro: só as dimensões pedidas em `breakdowns`, ou todas quando omitido. O filtro enviado vale para todas.

**Toggle entry**

**value** `string`

Valor da dimensão; envie-o como o filtro de mesmo nome. `(none)` significa que a requisição não tinha valor.

**label** `string | null`

Nome legível quando `value` é um código (o nome da rede de um `asn`); `null` caso contrário.

**requests** `integer`

Requisições com este valor.

**visits** `integer`

Visitas a páginas com este valor.

**bytes** `integer`

Bytes enviados aos visitantes.

Campos de `summary`, e dos mesmos totais em `previous.summary`:

**requests** `integer`

Requisições respondidas.

**visits** `integer`

Visitas a páginas: requisições que iniciam uma visita (uma página aberta direto ou vinda de outro site).

**bytes** `integer`

Bytes enviados aos visitantes.

**errors\_4xx** `integer`

Requisições respondidas com status 4xx.

**errors\_5xx** `integer`

Requisições respondidas com status 5xx.

**error\_rate\_4xx** `number`

`errors_4xx / requests`, de 0 a 1.

**error\_rate\_5xx** `number`

`errors_5xx / requests`, de 0 a 1.

**edge\_time\_p95\_ms** `number`

Percentil 95 do tempo de borda (quanto o visitante esperou pelo primeiro byte), em milissegundos. É o único número de velocidade que todos os planos recebem.

Campos de cada ponto de `series` (e de `previous.series`): `time`, `requests`, `visits`, `bytes`, `errors_4xx` e `errors_5xx`, com o mesmo significado de `summary`.

```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,
      "visits": 6310,
      "bytes": 412884113,
      "errors_4xx": 214,
      "errors_5xx": 9,
      "error_rate_4xx": 0.0116,
      "error_rate_5xx": 0.0005,
      "edge_time_p95_ms": 412
    },
    "series": [
      {
        "time": "2026-11-02T18:00:00Z",
        "requests": 702,
        "visits": 240,
        "bytes": 15331004,
        "errors_4xx": 8,
        "errors_5xx": 0
      },
      {
        "time": "2026-11-02T19:00:00Z",
        "requests": 731,
        "visits": 251,
        "bytes": 16120987,
        "errors_4xx": 11,
        "errors_5xx": 1
      }
    ],
    "previous": {
      "start": "2026-11-01T18:00:00Z",
      "end": "2026-11-02T18:00:00Z",
      "summary": {
        "requests": 16990,
        "visits": 5802,
        "bytes": 380112007,
        "errors_4xx": 190,
        "errors_5xx": 4,
        "error_rate_4xx": 0.0112,
        "error_rate_5xx": 0.0002,
        "edge_time_p95_ms": 455
      },
      "series": [
        {
          "time": "2026-11-01T18:00:00Z",
          "requests": 650,
          "visits": 222,
          "bytes": 14100222,
          "errors_4xx": 7,
          "errors_5xx": 0
        }
      ]
    },
    "breakdowns": {
      "country": [
        {
          "value": "BR",
          "label": null,
          "requests": 14210,
          "visits": 4902,
          "bytes": 318400221
        },
        {
          "value": "US",
          "label": null,
          "requests": 2105,
          "visits": 760,
          "bytes": 48112003
        },
        {
          "value": "PT",
          "label": null,
          "requests": 611,
          "visits": 204,
          "bytes": 13920110
        }
      ],
      "path": [
        {
          "value": "/",
          "label": null,
          "requests": 5210,
          "visits": 4100,
          "bytes": 90211003
        },
        {
          "value": "/pricing",
          "label": null,
          "requests": 1902,
          "visits": 1180,
          "bytes": 41230991
        }
      ],
      "referer": [
        {
          "value": "(none)",
          "label": null,
          "requests": 9120,
          "visits": 3300,
          "bytes": 201004112
        },
        {
          "value": "google.com",
          "label": null,
          "requests": 4410,
          "visits": 1890,
          "bytes": 98114003
        }
      ],
      "asn": [
        {
          "value": "28573",
          "label": "CLARO S.A.",
          "requests": 3300,
          "visits": 1100,
          "bytes": 70112008
        }
      ],
      "cache_status": [
        {
          "value": "hit",
          "label": null,
          "requests": 13011,
          "visits": 0,
          "bytes": 301100001
        },
        {
          "value": "dynamic",
          "label": null,
          "requests": 4100,
          "visits": 0,
          "bytes": 90113002
        }
      ]
    }
  }
}
```

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

### Observações

* Exige o escopo `apps:read` quando chamada com uma chave de API. Membros de workspace precisam de permissão para ler a aplicação.
* Disponível em todos os planos. Uma conta sem plano ativo recebe `PLAN_REQUIRED`.
* **Amostragem.** Com tráfego alto os números são estimados a partir de uma amostra e `sampled` vem `true`. Veja [Amostragem e atraso](https://docs.vertracloud.app/pt-br/web-analytics/sampling-and-delay.md).
* **Atraso.** Os dados se atualizam a cada cerca de 5 minutos, então as requisições mais novas podem levar alguns minutos para aparecer. Se os dados mais recentes não puderem ser lidos agora, uma resposta anterior pode voltar com `stale: true` (veja `generated_at`); caso contrário, a chamada falha com `ANALYTICS_BUSY`.
* **Privacidade.** A Vertra Cloud não guarda nada sobre os visitantes; guarda apenas totais por app (contagens, visitas, bytes, taxas de erro e tempos de resposta) por até 31 dias, apagados com o app. Nenhum IP, caminho, query string ou user agent é guardado. `ip` e `query` voltam sem máscara; mascarar é uma escolha do cliente que os exibe. Veja [Privacidade](https://docs.vertracloud.app/pt-br/web-analytics/privacy.md).

### Respostas de erro

| Status | Código | Quando |
| - | - | - |
| 401 | `AUTH_TOKEN_MISSING` / `API_KEY_INVALID` / `SESSION_REVOKED` | O header `Authorization` está ausente, a chave de API é inválida ou a sessão do painel foi revogada. |
| 403 | `API_KEY_IP_DENIED` / `API_KEY_SCOPE_DENIED` | A chave de API é usada de um IP fora da sua lista de permitidos, ou não tem o escopo `apps:read`. |
| 403 | `ACCESS_DENIED` | A aplicação pertence a outra conta, ou você não tem a permissão de workspace para lê-la. |
| 403 | `PLAN_REQUIRED` | A conta não tem plano ativo. |
| 404 | `APP_NOT_FOUND` | A aplicação não existe. |
| 400 | `VALIDATION_ERROR` | Um parâmetro falhou na validação, como `limit` fora do intervalo, `cursor` inválido ou data `start`/`end` malformada; `details.path` nomeia o campo. Também quando `compare_start` é malformado ou vem com `compare=false`. |
| 400 | `INVALID_RANGE` | `start` é posterior a `end`, `end` está no futuro ou a janela passa de 30 dias. Também quando o período que começa em `compare_start` termina depois de `start`, o que sobreporia a janela. |
| 400 | `ANALYTICS_RANGE_EXCEEDS_PLAN` | `start` é anterior ao que o plano consegue ler. `details.history_days` traz o limite em dias e `details.earliest` o `start` mais antigo aceito agora. Também quando `compare_start` é anterior ao que o plano consegue ler. |
| 429 | `RATE_LIMIT_EXCEEDED` | Muitas consultas seguidas. `details.retry_after` informa a espera em segundos; o header `Retry-After` vem sempre junto. |
| 503 | `ANALYTICS_BUSY` | Momento de alta demanda e sem resposta recente disponível para a consulta. Espere `details.retry_after` segundos e tente de novo. |


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