> For the complete documentation index, see [llms.txt](https://docs.ipcheck.ing/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ipcheck.ing/developer/pt-br/reference/api-endpoints.md).

# Endpoints da API

Todas as rotas da API do backend, suas proteções e os tempos de vida do cache de borda.

{% hint style="warning" %}
**Esta não é uma API pública.** Estas rotas existem para atender ao próprio frontend do MyIP. Elas são protegidas por uma `Referer` verificação; suas estruturas mudam sem aviso, e não há versionamento, política de descontinuação nem contrato de estabilidade. Não crie integrações com a `/api/*`. Esta página as documenta para que **você possa operar e depurar sua própria implantação**.
{% endhint %}

Toda rota é definida em `backend-server.js` e montada no servidor de backend (`BACKEND_PORT`, padrão `11966`). Em produção, `frontend-server.js` faz proxy `/api` de `FRONTEND_PORT` (padrão `18966`) para o backend, então, de fora da implantação, tudo fica em `/api` em uma única origem. Veja [Backend](/developer/pt-br/architecture/backend.md).

## Middleware global

Eles se aplicam a **toda** `/api/*` rota, na ordem de montagem.

| Ordem | Middleware                         | Comportamento                                                                                                                                                                                                                                                                                                                                                                                                                            |
| ----- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1     | `pino-http`                        | Somente quando `LOG_HTTP=true`. Registra método, URL e status. Montado antes dos limitadores para que os 429 sejam registrados.                                                                                                                                                                                                                                                                                                          |
| 2     | `express-rate-limit`               | Somente quando `SECURITY_RATE_LIMIT` é diferente de zero. Máximo de N requisições por IP a cada janela de 20 minutos → `429 {"message":"Muitas requisições"}`. Ignora `/api/monitoring`. Não é a única origem de um 429: `/api/invisibility` e `/api/dnsleaktest/session/:token` podem repassar um do upstream, distinguível pelo seu `code: "quota_exceeded"` corpo, e `/api/persona/evaluate` repassa um 429 do upstream literalmente. |
| 3     | `express-slow-down`                | Somente quando `SECURITY_DELAY_AFTER` é diferente de zero. Depois de N requisições por IP por janela de 60 minutos, adiciona `acertos × 400 ms` de atraso. Ignora `/api/monitoring`.                                                                                                                                                                                                                                                     |
| 4     | `express.json({ limit: '500kb' })` | o processamento do corpo JSON. Corpos acima de 500 KB recebem um `413`.                                                                                                                                                                                                                                                                                                                                                                  |
| 5     | `Cache-Control: no-store`          | **Padrão para toda rota.** Rotas que querem cache na borda o substituem explicitamente.                                                                                                                                                                                                                                                                                                                                                  |
| 6     | `requireReferer`                   | Rejeita qualquer requisição cujo `Referer` hostname não seja `localhost` ou esteja em `ALLOWED_DOMAINS`.                                                                                                                                                                                                                                                                                                                                 |

### Filtro de Referer

`requireReferer` é a primeira coisa que toda requisição encontra. A correspondência é exata por hostname contra `['localhost', ...ALLOWED_DOMAINS.split(',')]`.

| Condição                                       | Resposta                                   |
| ---------------------------------------------- | ------------------------------------------ |
| Nenhum `Referer` cabeçalho algum               | `403 {"error":"O que você está fazendo?"}` |
| `Referer` presente, mas hostname não permitido | `403 {"error":"Acesso negado"}`            |
| `Referer` não pode ser interpretado como URL   | `403 {"error":"Acesso negado"}`            |

É por isso que `curl http://your-host:18966/api/configs` sempre retorna 403 — o curl não envia nenhum `Referer`. Veja [Opções de segurança](/developer/pt-br/configuration/security-options.md).

### Cache

O `cacheable(seconds)` fábrica de middleware envolve `res.json` e define `Cache-Control: public, max-age=<seconds>` **somente em respostas 2xx**, então erros nunca são armazenados em cache na borda. Ele também guarda o valor em `res.locals.cacheControl` para handlers que fazem streaming binário e contornam `res.json` (somente `/api/map` faz isso).

Tudo que não estiver marcado como cacheable herda o `no-store` padrão.

### Validador

Os validadores ficam em `common/guards.js` e são aplicados por rota. Todos eles rejeitam com `400` e uma `erro` string JSON.

| Validador                  | Lê                      | Valida                                                                                                                                                                                                                                                                                                                                                                                                       | Erros                                                                                    |
| -------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
| `requirePublicIP()`        | `?ip`                   | IPv4 ou IPv6 válidos, e roteáveis publicamente — espaço reservado (RFC 1918, loopback, CGNAT, link-local, documentação, multicast) nunca chega a um handler                                                                                                                                                                                                                                                  | `Nenhum endereço IP fornecido` / `Endereço IP inválido` / `Não é um endereço IP público` |
| `requireValidDomain()`     | `?domain`               | Domínio sintático; converte o valor para minúsculas no próprio local para que o cache na borda veja uma forma canônica. Os rótulos podem carregar um sublinhado inicial (nomes RFC 8552 como `_dmarc.example.com`); o TLD não pode. É uma fábrica — `/api/dnsresolver` monta como `requireValidDomain('hostname')`, e as strings de erro permanecem `domínio` independentemente de como o parâmetro se chame | `Nenhum domínio fornecido` / `Domínio inválido`                                          |
| `requireValidPrefix()`     | `?prefix`               | CIDR bem formado (qualquer comprimento — o frontend decide a quantização)                                                                                                                                                                                                                                                                                                                                    | `Nenhum prefixo fornecido` / `Prefixo inválido`                                          |
| `requireValidASN()`        | `?asn`                  | Numérico, opcional `AS` prefixo; remove o prefixo no próprio valor                                                                                                                                                                                                                                                                                                                                           | `Nenhum ASN fornecido` / `ASN inválido`                                                  |
| `requireValidCountry()`    | `?country`              | Exatamente duas letras ASCII (um código de país alpha-2); converte o valor para maiúsculas no próprio local para que o cache na borda veja uma chave por país                                                                                                                                                                                                                                                | `Nenhum país fornecido` / `País inválido`                                                |
| `requireValidProviderId()` | `?id`                   | Pertencimento à lista de permissões de slugs de provedores do status do serviço                                                                                                                                                                                                                                                                                                                              | `Nenhum ID de provedor fornecido` / `ID de provedor inválido`                            |
| `requireValidRecordType()` | `?type`                 | Pertencimento em `DNS_RECORD_TYPES` (`common/dns-record-types.js`) — os tipos de registro DNS para os quais o resolvedor responde. Converte o valor para maiúsculas no próprio local, então o parâmetro não diferencia maiúsculas de minúsculas                                                                                                                                                              | `Nenhum tipo de registro fornecido` / `Tipo de registro inválido`                        |
| `requireValidReportId()`   | parâmetro de rota `:id` | Exatamente 22 caracteres base64url (16 bytes aleatórios)                                                                                                                                                                                                                                                                                                                                                     | `ID do relatório inválido`                                                               |

## Geolocalização de IP

Todos eles retornam a mesma estrutura normalizada (`ip`, `city`, `region`, `country`, `country_name`, `country_code`, `latitude`, `longitude`, `timezone`, `asn`, `org`), produzida pela `makeGeoHandler` fábrica em `common/geo-handler.js`. `timezone` é a exceção a essa fábrica: o `withTimeZone()` middleware o deriva a partir das coordenadas já presentes na resposta e o acrescenta, e é por isso que `/api/ipchecking` também o traz. Veja [Fontes de dados de IP](/developer/pt-br/architecture/ip-data-sources.md).

`/api/ipchecking` também traz um bloco `advancedData` Seus campos só contêm valores reais para chamadores autenticados dentro da cota mensal; caso contrário, cada campo do bloco é o sentinela de string `sign_in_required` ou `quota_exceeded` — a resposta permanece `200` e os campos de geolocalização não são afetados. O `transform-ip-data.js` do frontend propaga os sentinelas para que a interface possa mostrar o aviso correspondente.

| Rota                   | Parâmetros                 | Validador · Cache            | Finalidade                                                                                                                                                       |
| ---------------------- | -------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /api/ipinfo`      | `ip`                       | `requirePublicIP` · 1 dia    | Geolocalização via ipinfo.io. `IPINFO_API_KEY` opcional.                                                                                                         |
| `GET /api/ipapicom`    | `ip`, `lang` (padrão `en`) | `requirePublicIP` · 1 dia    | Geolocalização via ip-api.com. Sem chave.                                                                                                                        |
| `GET /api/ipsb`        | `ip`                       | `requirePublicIP` · 1 dia    | Geolocalização via api.ip.sb. Sem chave.                                                                                                                         |
| `GET /api/ipapiis`     | `ip`                       | `requirePublicIP` · 1 dia    | Geolocalização via api.ipapi.is; também retorna `isHosting` / `isProxy`. Requer `IPAPIIS_API_KEY`.                                                               |
| `GET /api/ip2location` | `ip`                       | `requirePublicIP` · 1 dia    | Geolocalização via ip2location.io. Requer `IP2LOCATION_API_KEY`.                                                                                                 |
| `GET /api/maxmind`     | `ip`, `lang` (opcional)    | `requirePublicIP` · 1 dia    | Consulta local GeoLite2 City + ASN. Requer credenciais MaxMind ou `.mmdb`; **503** arquivos .mmdb pré-carregados quando os bancos de dados não estão carregados. |
| `GET /api/ipchecking`  | `ip`, `lang` (padrão `en`) | `requirePublicIP` · no-store | Geolocalização via a API privada IPCheck.ing. Requer `IPCHECKING_API_KEY` + `IPCHECKING_API_ENDPOINT`; `500 {"error":"A chave da API está ausente"}` sem eles.   |

**Nenhum handler valida `?lang` contra uma lista de permissões.** Em `/api/maxmind` a tag bruta vai para `lookupMaxMind()`, que a normaliza para os idiomas que o banco City fornecido realmente contém — `de`, `en`, `es`, `fr`, `ja`, `pt-BR`, `ru`, `zh-CN` (`SUPPORTED_LANGS` em `common/maxmind-service.js`) — correspondendo primeiro à tag exata, depois ao idioma base e depois a um idioma irmão da mesma família (`zh-TW` lê `zh-CN`), e então recuando para `en`. Em `/api/ipapicom` e `/api/ipchecking` a tag é encaminhada ao upstream sem alterações, que cuida da própria resolução.

O frontend envia o `apiTag` do registro para a localidade ativa da interface, não o próprio código da interface — uma interface em chinês tradicional já solicita `zh-CN`, então a etapa de família acima existe para qualquer outro chamador. Veja [i18n](/developer/pt-br/development/i18n.md).

Falhas do upstream nos handlers de geolocalização retornam `500 {"error": "<mensagem>"}`.

## Ferramentas de rede

| Rota                                  | Parâmetros                                                                                   | Validador · Cache                                                        | Finalidade                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| ------------------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /api/whois`                      | `q` (IP ou domínio)                                                                          | inline · 1 dia                                                           | Consulta WHOIS / RDAP. IPs vão primeiro para RDAP com `whoiser` como fallback. Valida inline porque `q` aceita qualquer uma das formas: `400 IP ou endereço inválido`, ou `400 Não é um endereço IP público` para espaço reservado; `404` quando o TLD não publica nem WHOIS nem RDAP.                                                                                                                                                                                                                                                                                                                           |
| `GET /api/dnsresolver`                | `hostname`, `type`                                                                           | `requireValidDomain('hostname')` + `requireValidRecordType()` · no-store | Resolve um hostname em vários resolvedores DNS simples e DoH em paralelo, para comparação de contaminação.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `GET /api/dnsleaktest/session/:token` | rota `:token` (32 caracteres hex), `lang` (opcional, encaminhado como está)                  | inline · no-store                                                        | Busca um resultado aprimorado da sessão de vazamento DNS. Encaminha os cabeçalhos da requisição (incluindo `Authorization`) e repassa o status do upstream literalmente — incluindo `429` com `code: "quota_exceeded"` quando a cota mensal se esgota. Requer `IPCHECKING_API_KEY` + `IPCHECKING_API_ENDPOINT`.                                                                                                                                                                                                                                                                                                  |
| `GET /api/ooni-blocking`              | `domínio`                                                                                    | `requireValidDomain` · 1 dia                                             | Agregado de censura da OONI em uma janela UTC de 30 dias; consulta tanto o domínio raiz quanto a variante `www.` e mescla.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `GET /api/globalping-probes`          | —                                                                                            | — · 7 dias                                                               | Inventário compacto por país de probes Globalping online, para os seletores de país de MTR / latência / censura.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `GET /api/macchecker`                 | `mac` (exatamente 12 caracteres hex após remover `:` e `-`)                                  | inline · 30 dias                                                         | Consulta de fornecedor IEEE OUI via maclookup.app. `MAC_LOOKUP_API_KEY` opcional.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `GET /api/map`                        | `latitude`, `longitude`, `language` (2 letras), `CanvasMode` (`Escuro` para o estilo escuro) | inline · 1 ano                                                           | Faz proxy de um JPEG do Google Static Maps. **Retorna binário**, não JSON. Precisa de `GOOGLE_MAP_API_KEY`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `GET /api/invisibility`               | `id` (28 caracteres alfanuméricos)                                                           | inline · no-store                                                        | Consulta o resultado de detecção de proxy. Um 404 do upstream é traduzido para `200 {"status":"pending"}`; um 429 do upstream passa adiante como `429 {"error":…,"code":"quota_exceeded"}` (quota mensal esgotada — o frontend faz correspondência pelo código). Precisa de `IPCHECKING_API_KEY` + `IPCHECKING_API_ENDPOINT`.                                                                                                                                                                                                                                                                                    |
| `POST /api/persona/evaluate`          | corpo JSON `{ persona, observation }`                                                        | inline · no-store                                                        | Avalia os sinais observados de um navegador em relação a uma persona declarada, para a ferramenta In-depth Persona Check. `405` em qualquer outro método; `400 {"error":"No persona provided"}` sem `persona.country`; `500 {"error":"A chave da API está ausente"}` sem `IPCHECKING_API_KEY` + `IPCHECKING_API_ENDPOINT`. Repassa os cabeçalhos do chamador (veja abaixo) e repassa o status e o payload do upstream literalmente — um `429` significa que a cota mensal da conta foi gasta, e o frontend se baseia apenas no status. Um avaliador inacessível retorna `502 {"error":"Upstream fetch failed"}`. |

As três rotas de API privada nesta seção — `/api/dnsleaktest/session/:token`, `/api/invisibility` e `/api/persona/evaluate` — encaminham os cabeçalhos da requisição do chamador para o upstream, porque essa API precisa do contexto do chamador (`Accept-Language`, o `Authorization` token). `/api/persona/evaluate` é a que primeiro descarta os cabeçalhos que descrevem este salto em vez do chamador (`host`, `content-length`, `content-type`, `connection`, `transfer-encoding`): ela reserializa o corpo JSON, então o `Content-Length` já não descreve o que sai.

## ASN & BGP

Todos os dados do Cloudflare Radar passam pela única `GET /api/cfradar` rota. Um `view` parâmetro escolhe o conjunto de dados; cada view traz seus próprios guardrails e TTL de cache de borda. Ausência de `view` retorna `400 {"error":"No view provided"}`, um valor desconhecido `400 {"error":"Invalid view"}`, qualquer método que não seja GET `405`, e uma implantação sem `CLOUDFLARE_API_KEY` responde `500 {"error":"A chave da API está ausente"}` — depois das proteções da view, então parâmetros inválidos continuam como 400 mesmo em implantações sem chave.

| Rota                                    | Parâmetros                    | Validador · Cache               | Finalidade                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| --------------------------------------- | ----------------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /api/cfradar?view=asn`             | `asn`                         | `requireValidASN` · 30 dias     | Perfil do Cloudflare Radar para um ASN: informações da entidade, divisões de tráfego / adoção de 7 dias, contagens de prefixos IPv4 / IPv6 anunciados, contagens de AS upstream / downstream / peer, e agregados de qualidade de speed test (largura de banda, latência, jitter). Falhas parciais de segmentos são registradas e atendidas — as contagens de relacionamentos recorrem ao snapshot local da CAIDA; uma falha total retorna 500.                                                                                                                                                                                                                                                                                                                                           |
| `GET /api/cfradar?view=country-traffic` | `country`, `human` (opcional) | `requireValidCountry` · 30 dias | Mapa de calor da atividade online por país: agrega a série temporal horária de requisições HTTP do Cloudflare Radar ao longo de uma janela de 28 dias em uma matriz de dia da semana/hora 7×24, com segunda-feira primeiro, retornada como `{"trafficMatrix": …}`. De propósito no nível do país — um ASN global não tem um único ritmo diurno. `human=1` restringe ao tráfego provavelmente humano; apenas essa string exata conta, o que mantém o cache em duas chaves por país. `trafficMatrix: null` (sem série utilizável) é um valor válido, em cache `200`, não um erro. A matriz permanece em UTC — a resposta é armazenada em cache na borda entre fusos horários, então o frontend faz a rotação das horas. Falha no upstream retorna `500 {"error":"Internal server error"}`. |
| `GET /api/cfradar?view=outages`         | —                             | — · 1 hora                      | Feed global de interrupções da internet para o painel Earth Online: mescla as interrupções verificadas e as anomalias de tráfego do Cloudflare Radar ao longo de uma janela de 30 dias, remove anomalias já promovidas a interrupção e ordena primeiro os eventos em andamento (do mais recente para o mais antigo dentro de cada grupo, limitado a 30). Uma fonte com falha degrada para um feed parcial; as duas falhando retornam 500.                                                                                                                                                                                                                                                                                                                                                |
| `GET /api/asn-history`                  | `prefix` (CIDR)               | `requireValidPrefix` · 30 dias  | Anúncios históricos de BGP para um prefixo, do routing-history do RIPEstat, com percentuais relativos de visibilidade. Upstream que não retorna 2xx devolve `502 {"error":"Upstream error"}`. `RIPESTAT_SOURCE_APP` opcional.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            |
| `GET /api/asn-connectivity`             | `asn`                         | `requireValidASN` · 30 dias     | Grafo de topologia do upstream de um ASN em direção aos backbones Tier-1, construído a partir do snapshot local as-rel da CAIDA. As arestas são classificadas como `trânsito` (p2c) ou `peering` (p2p com Tier 1s); uma origem Tier-1 retorna suas arestas de peering para o restante do clique em vez de um grafo vazio.                                                                                                                                                                                                                                                                                                                                                                                                                                                                |

## Status do serviço

Ambos os handlers leem um snapshot em memória mantido por um coletor em segundo plano em um cronograma fixo de 5 minutos. Nenhum deles acessa um upstream no momento da requisição, então o volume de requisições nunca afeta a carga do upstream.

| Rota                             | Parâmetros              | Validador · Cache                | Finalidade                                                                   |
| -------------------------------- | ----------------------- | -------------------------------- | ---------------------------------------------------------------------------- |
| `GET /api/service-status`        | —                       | — · 5 min                        | Visão geral: uma luz de status por provedor, sem arrays pesados de detalhes. |
| `GET /api/service-status/detail` | `id` (slug do provedor) | `requireValidProviderId` · 5 min | Os subcomponentes de um provedor mais incidentes recentes.                   |

## Plataforma

| Rota                             | Parâmetros                                                       | Validador · Cache                                  | Finalidade                                                                                                                             |
| -------------------------------- | ---------------------------------------------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `GET /api/configs`               | —                                                                | — · 1 hora                                         | Flags de recurso para o frontend. Retorna **apenas booleanos**, nunca valores de chave.                                                |
| `GET /api/github-stars`          | —                                                                | — · 1 dia                                          | Contagem de estrelas para `jason5ng32/MyIP`, obtida sem autenticação.                                                                  |
| `GET /api/getuserinfo`           | — (encaminha os cabeçalhos da requisição, incl. `Authorization`) | — · no-store                                       | Perfil do usuário autenticado da API complementar. Precisa de `IPCHECKING_API_KEY` + `IPCHECKING_API_ENDPOINT`.                        |
| `PUT /api/updateuserachievement` | corpo JSON                                                       | — · no-store                                       | Registra o desbloqueio de uma conquista. Precisa de `IPCHECKING_API_KEY` + `IPCHECKING_API_ENDPOINT`.                                  |
| `POST /api/report`               | corpo JSON `{ report, ttlDays }`                                 | whitelist de schema + limite de tamanho · no-store | Armazena um relatório de diagnóstico compartilhável no Workers KV e retorna seu id. Precisa de todos os três `CLOUDFLARE_*` variáveis. |
| `GET /api/report/:id`            | rota `:id` (22 caracteres)                                       | `requireValidReportId` · no-store                  | Lê um relatório armazenado para a página somente leitura `/r/:id` . Precisa dos mesmos três `CLOUDFLARE_*` variáveis.                  |
| `POST /api/monitoring`           | corpo bruto do envelope (máx. 10 MB)                             | limitador próprio · no-store                       | Túnel Sentry de primeira parte. **Montado somente quando `VITE_SENTRY_DSN_FRONTEND` está definido.**                                   |

### `/api/configs` resposta

Cada campo é um booleano. `originalSite` é `true` somente quando o `Referer` hostname da requisição é um dos hostnames canônicos do IPCheck.ing.

{% code title="GET /api/configs" %}

```json
{
  "map": false,
  "ipInfo": false,
  "ipChecking": false,
  "ip2location": false,
  "originalSite": false,
  "cloudFlare": false,
  "ipapiis": false,
  "reportSharing": false
}
```

{% endcode %}

### Códigos de status de compartilhamento de relatórios

| Código | Significado                                                                                        |
| ------ | -------------------------------------------------------------------------------------------------- |
| `503`  | Os três `CLOUDFLARE_*` variáveis não estão todas definidas.                                        |
| `400`  | O corpo do relatório falhou na validação do schema (`{"error":"Invalid report","details":[...]}`). |
| `413`  | O relatório serializado excede 256 KB.                                                             |
| `404`  | Em `GET`: relatório não encontrado ou seu TTL no KV expirou.                                       |

`ttlDays` deve ser `1`, `3` ou `7`; qualquer outro valor é silenciosamente reduzido para `1`.

### `/api/monitoring`

Montado somente quando `VITE_SENTRY_DSN_FRONTEND` está definido no **processo de backend**. Ele tem um limitador dedicado de 600 requisições por IP por janela de 20 minutos e é explicitamente ignorado por ambos os limitadores globais — a telemetria compartilhando a cota do app é como o relatório de erros morre silenciosamente. O corpo é analisado com `express.raw` usando um combinador de tipo coringa, porque os envelopes do Sentry Replay são enviados sem `Content-Type` algum.

## Resumo de TTL de cache

| TTL        | Rotas                                                                                                                                                                                                                                        |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 5 minutos  | `/api/service-status`, `/api/service-status/detail`                                                                                                                                                                                          |
| 1 hora     | `/api/configs`, `/api/cfradar?view=outages`                                                                                                                                                                                                  |
| 1 dia      | `/api/ipinfo`, `/api/ipapicom`, `/api/ipsb`, `/api/ipapiis`, `/api/ip2location`, `/api/maxmind`, `/api/whois`, `/api/github-stars`, `/api/ooni-blocking`                                                                                     |
| 7 dias     | `/api/globalping-probes`                                                                                                                                                                                                                     |
| 30 dias    | `/api/cfradar` (`view=asn`, `view=country-traffic`), `/api/asn-history`, `/api/asn-connectivity`, `/api/macchecker`                                                                                                                          |
| 1 ano      | `/api/map`                                                                                                                                                                                                                                   |
| `no-store` | todo o resto — `/api/ipchecking`, `/api/dnsresolver`, `/api/dnsleaktest/session/:token`, `/api/invisibility`, `/api/persona/evaluate`, `/api/getuserinfo`, `/api/updateuserachievement`, `/api/report`, `/api/report/:id`, `/api/monitoring` |

Os TTLs são escolhidos de acordo com o ritmo natural de atualização de cada upstream. Relatórios compartilhados permanecem `no-store` deliberadamente: um cache de borda poderia servir um relatório após o vencimento no KV, e dados diagnósticos privados não devem ficar em um cache público.

## Não-`/api` rotas

`frontend-server.js` atende todo o resto: a saída estática `dist/` de saída com controle por classe de ativo `Cache-Control`, e um fallback de histórico de SPA que retorna `index.html` (com `no-store`) para navegações GET cujo segmento final do caminho não tem extensão de arquivo.

Uma parte do tráfego do frontend ignora este backend completamente: **Earth Online**'s metade social (compositor de status, feed Latest, mapa de visitantes, beacon de visita) chama o serviço externo nomeado por `VITE_PULSE_BEACON_URL` diretamente do navegador, então essas requisições nunca aparecem em `/api` e nenhuma das proteções ou regras de cache acima se aplica a elas. Elas ficam desativadas a menos que essa variável seja definida no build. O feed global de interrupções do painel é diferente — ele usa a `GET /api/cfradar?view=outages` rota documentada e precisa apenas de `CLOUDFLARE_API_KEY` — veja [Recursos vinculados ao IPCheck.ing](/developer/pt-br/configuration/features-tied-to-ipcheck-ing.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.ipcheck.ing/developer/pt-br/reference/api-endpoints.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
