# Por que uma requisição proxy esgotou as tentativas

> URL: https://foura.ai/pt/docs/troubleshooting/proxy-attempt-report
> Updated: 2026-09-30
> Index: https://foura.ai/llms.txt

## O problema

Uma chamada `POST /api/proxy/` retorna com um erro e sem dados. A mensagem é curta e sempre no mesmo formato:

```json
{
  "error": "Download maxTry limit reached",
  "total": 34.812,
  "request": { "...": "..." }
}
```

Essa frase soa idêntica se todas as saídas foram bloqueadas, se todas as saídas estavam inativas ou se o FourA buscou a página real em quase todas as tentativas e suas próprias regras `validate` a descartaram. Esses três casos exigem correções opostas.

## A resposta: `attemptReport`

Cada chamada de Proxy que esgotou suas tentativas e falhou carrega um objeto `attemptReport` ao lado do erro, incluindo aquela que terminou com `"error": "Timeout"`. Um nome de host que não resolve falha antes de qualquer tentativa, com `status: 0` e nenhum relatório. Ele contabiliza o que as tentativas realmente encontraram:

```json
{
  "error": "Download maxTry limit reached",
  "attemptReport": {
    "total": 25,
    "noResponse": 0,
    "defense": 0,
    "contentRejected": 25,
    "statusRejected": 0,
    "other": 0,
    "vendors": [],
    "profilesTried": ["default"],
    "summary": "25 attempt(s): 25 returned HTTP 200 with no defense present and were rejected only by your validate.data - the page was fetched, your content rule did not match it"
  },
  "total": 34.812
}
```

A string `error` permanece deliberadamente inalterada, para que um client que faz correspondência com ela continue funcionando. Leia `attemptReport.summary` para obter uma resposta em uma única linha, ou as contagens quando quiser criar ramificações condicionais baseadas nelas.

### Campos

| Campo | Tipo | O que conta |
|-------|------|-------------|
| `total` | integer | Tentativas realizadas |
| `noResponse` | integer | A saída nunca respondeu, ou o site não respondeu a tempo |
| `defense` | integer | O site respondeu e um provedor de verificação de bot foi reconhecido nessa resposta |
| `contentRejected` | integer | HTTP 200, sem verificação de bot, rejeitado apenas pelo seu `validate.data` |
| `statusRejected` | integer | O site respondeu, sem verificação de bot, rejeitado pelo seu `validate.status` |
| `other` | integer | Respondeu, e nenhum dos casos acima |
| `vendors` | string[] | Cada provedor de verificação de bot reconhecido em qualquer lugar da tarefa |
| `profilesTried` | string[] | Os perfis de navegador que a tarefa enviou, na ordem de primeiro uso. `default` significa que a request saiu exatamente como você a escreveu. |
| `summary` | string | Uma frase gerada a partir das contagens. Seguro para registrar em logs ou exibir a um usuário. |

## Como interpretar

### `contentRejected` está alto

As páginas chegaram. Sua regra `validate.data` não correspondeu a elas.

Este é o caso que você mesmo pode corrigir, e é o que todos os outros sinais ocultam: as requests parecem falhas em todas as métricas, enquanto a FourA estava entregando conteúdo real o tempo todo. Faça o fetch da página uma vez através de `POST /api/single/` sem nenhum `validate`, veja o que realmente retorna e reescreva a regra com base nisso.

Uma causa comum é uma única regra aplicada a um conjunto de páginas que não são todas iguais. Um seletor que existe em páginas de artigos e não em páginas de vídeos falhará toda vez que atingir uma página de vídeo, permanentemente, com custo total.

### `statusRejected` está alto

O site respondeu e sua regra `validate.status` recusou a resposta. Se esses status forem 401, 403, 429 ou 503, o site está recusando o client em vez de informar que a página não existe. Tente:

- Outro perfil de navegador (`browser`, `os`, `version` no objeto interno `request`)
- `exitCountries` se o conteúdo tiver restrição regional
- `POST /api/browser/` se a recusa exigir JavaScript para ser liberada

### `defense` está alto

Uma verificação de bot foi reconhecida nas respostas, e `vendors` indica qual. Consulte [Site checks](https://foura.ai/docs/api/site-checks) para ver o que a FourA resolve atualmente e o que ela apenas reporta. Se o provedor não for um dos que são resolvidos neste endpoint, migre a chamada para `POST /api/browser/` ou `POST /api/auto/`.

### `noResponse` está alto

As saídas não responderam, portanto nada foi identificado sobre o destino. Aumente `maxTries`, aumente `timeout_ms` e verifique se a URL resolve a partir da internet pública.

### `other` está alto

O site respondeu com um status, nenhuma verificação de bot foi reconhecida e a tentativa falhou por outro motivo, como uma regra `validate.headers`. Um destino mais lento do que o seu `timeout_ms` é contabilizado em `noResponse`.

## Rotação de perfis de navegador

Quando um site recusa o navegador enviado pela FourA, o Proxy para de insistir nele e tenta outra família do [catálogo de perfis públicos](https://foura.ai/docs/api/endpoints). Isso não consome tentativas adicionais: a rotação altera o que uma nova tentativa envia, nunca se ela acontece ou não.

O Proxy também lembra, por site, a última família que funcionou ali depois que o site recusou o padrão. Uma request futura para esse site pode começar nessa família desde a primeira tentativa, e a FourA avança para a próxima família assim que o site começar a recusar essa também. Um navegador mobile só é lembrado para sites que respondem JSON.

`profilesTried` é como você vê isso acontecer. Uma única entrada significa que todas as tentativas enviaram o mesmo navegador: `default` é a request como foi escrita, e um ID de catálogo é a família que a FourA já havia memorizado para aquele site. Múltiplas entradas significam que a rotação foi executada e o site recusou cada uma delas, o que é uma situação diferente de não ter rotacionado.

Em uma response de Proxy **bem-sucedida**, o campo `profile` aparece apenas quando a rotação escolheu um navegador que você não solicitou:

```json
{
  "status": 200,
  "data": "<!doctype html>...",
  "proxy": "A1B2C3",
  "profile": "...",
  "total": 4.108
}
```

O valor é um ID de catálogo de `GET /api/profiles`. A ausência significa que a request foi enviada exatamente como escrita. A presença significa que o navegador que funcionou não foi o que você digitou, portanto passe esse ID de volta como `profile` nas chamadas seguintes em vez de repetir o que falhou. O painel [Playground](https://foura.ai/docs/dashboard/playground) faz isso por você com **Carry**.

Um `profile`, `browser`, `os` ou `version` explícito na sua request nunca é sobrescrito. O mesmo vale para uma request que contenha seu próprio header `User-Agent` ou `Cookie`, pois uma autorização está vinculada à assinatura que a obteve.

## Lendo isso no código

```python
import requests

API = "https://eu.api.foura.ai"
H = {"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"}

r = requests.post(f"{API}/api/proxy/", headers=H, json={
    "maxTries": 5,
    "request": {
        "method": "GET",
        "url": "https://example.com/product/42",
        "validate": {"data": {"accept": ["Add to cart"]}},
    },
}).json()

if "error" in r:
    rep = r.get("attemptReport", {})
    print(rep.get("summary", r["error"]))

    if rep.get("contentRejected", 0) > rep.get("total", 0) / 2:
        # The pages arrived. The validate rule is what threw them away.
        raise SystemExit("validate.data did not match the real page")
    if rep.get("defense", 0):
        print("bot check met:", ", ".join(rep.get("vendors", [])))
```

## Relacionados

- [Endpoints da API](https://foura.ai/docs/api/endpoints): A referência completa de request e response do Proxy
- [Verificações de site](https://foura.ai/docs/api/site-checks): Vendors, `defense` e como reproduzir uma autorização
- [Resultados da Request](https://foura.ai/docs/api/outcomes): Como uma response rejeitada é classificada e faturada
- [Problemas Comuns](https://foura.ai/docs/troubleshooting/common-issues): Outros problemas e suas correções
- [Escolhendo o Endpoint Correto](https://foura.ai/docs/guides/choosing-task-type): Quando o Proxy é a ferramenta errada
