{"openapi":"3.1.0","info":{"title":"Equatorial Faturas API","summary":"Consulta de faturas em aberto da Equatorial Energia (AL, AP, MA, PA, PI).","description":"\nConsulta as **faturas em aberto** no portal *Pagamento Simplificado* da\n**Equatorial Energia**.\n\n### Estados atendidos\nA consulta funciona apenas nos estados onde a Equatorial opera. O campo `estado`\naceita a **sigla** ou o **nome** (com ou sem acento):\n\n| Sigla | Estado |\n|-------|--------|\n| `AL`  | Alagoas |\n| `AP`  | Amapá |\n| `MA`  | Maranhão |\n| `PA`  | Pará |\n| `PI`  | Piauí |\n\nQualquer outro estado retorna `codigo: \"estado_invalido\"`.\n\n### Como funciona (por baixo dos panos)\nO portal protege a consulta com três camadas de anti-bot — **Imperva Incapsula**,\n**reCAPTCHA Enterprise v3** e **Transmit Security**. Os tokens de reCAPTCHA e Transmit\nsó nascem dentro de um navegador real, então a API dispara um **Chromium real\n(Playwright)** que replica exatamente o que o titular faria: escolhe o estado, informa\nCPF/CNPJ e data de nascimento, clica em *Entrar* e lê as faturas renderizadas na tela.\n\n> ⚠️ **Não funciona em headless** — o reCAPTCHA Enterprise penaliza navegador sem tela.\n> Rode com `HEADLESS=false` (local) ou headed sob Xvfb (Docker).\n\n### Fluxo de uma chamada\n1. Você envia `POST /consulta` com `estado`, `documento` e `nascimento`.\n2. A API abre um **contexto efêmero** (cookies/cache zerados) — isso evita o acúmulo\n   que faz o portal pedir RG.\n3. Faz login (com retry automático, pois o reCAPTCHA falha esporadicamente).\n4. Percorre todas as contas do titular e coleta as faturas em aberto.\n5. Devolve um JSON com totais e a lista de `contas` → `faturas`.\n\n### Possíveis resultados (campo `codigo`)\n| `codigo` | Significado | O que fazer |\n|----------|-------------|-------------|\n| `ok` | Consulta concluída | Ler `contas` |\n| `rg_obrigatorio` | Portal exigiu RG | Reenviar incluindo o campo `rg` |\n| `login_falhou` | Dados recusados / anti-bot | Conferir dados; tentar mais tarde |\n| `timeout` | Excedeu o tempo limite | Tentar novamente |\n| `estado_invalido` | Estado não suportado | Usar AL, AP, MA, PA ou PI |\n| `erro` | Falha inesperada | Ver `mensagem` |\n\nA API **nunca** retorna HTTP 500 ao cliente: erros vêm como `200` com `sucesso=false`\ne o `codigo` correspondente.\n\n### ⚖️ Uso legítimo (LGPD)\nFerramenta para **advogado correspondente** consultar faturas **em nome de clientes**,\nmediante autorização/procuração. Os dados de acesso são os mesmos que o próprio titular\nusaria. Não armazene dados além do necessário.\n","contact":{"name":"Equatorial Faturas"},"license":{"name":"Uso interno / LGPD"},"version":"1.0"},"servers":[{"url":"https://api.x4t.lat","description":"Produção (VPS + Traefik/HTTPS)"},{"url":"http://127.0.0.1:8000","description":"Local (desenvolvimento)"}],"paths":{"/consulta":{"post":{"tags":["Consulta"],"summary":"Consultar faturas em aberto de um titular","description":"Consulta as faturas em aberto de um titular no portal da Equatorial.\n\n**Entrada mínima:** `estado`, `documento` e `nascimento`. Inclua `rg` apenas se uma\nchamada anterior tiver retornado `codigo: \"rg_obrigatorio\"`.\n\n**Importante:**\n- A resposta é sempre HTTP `200`; o sucesso/erro vem no campo `codigo`.\n- Cada consulta abre um navegador real e pode levar dezenas de segundos\n  (limite `TIMEOUT_CONSULTA`, padrão 90s).\n- A concorrência é limitada por `MAX_CONCORRENCIA` (padrão 2) — chamadas extras\n  aguardam em fila.","operationId":"consulta_consulta_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsultaRequest"}}},"required":true},"responses":{"200":{"description":"Consulta processada. **Sempre 200** — verifique o campo `codigo` para distinguir sucesso de erro/bloqueio.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsultaResponse"},"examples":{"ok":{"summary":"Faturas encontradas","value":{"sucesso":true,"codigo":"ok","mensagem":"","estado":"PA","documento":"025.092.642-30","titular":"Valeria Do Nascimento Borges","consultado_em":"2026-06-27T20:46:12+00:00","total_faturas":1,"total_em_aberto":96.79,"contas":[{"indice":1,"contrato":"003016849234","endereco":"Governador Magalhães Barata, São Brás","total_em_aberto":96.79,"faturas":[{"status":"Vencida","referencia":"2026/06","vencimento":"26/06/2026","valor":"R$ 96,79","valor_num":96.79}]}]}},"rg_obrigatorio":{"summary":"Portal exigiu RG","value":{"sucesso":false,"codigo":"rg_obrigatorio","motivo":"rg_obrigatorio","mensagem":"O portal exigiu o RG para este CPF/CNPJ. Reenvie a consulta incluindo o campo 'rg' no payload.","estado":"PA","documento":"025.092.642-30"}},"login_falhou":{"summary":"Dados recusados ou anti-bot","value":{"sucesso":false,"codigo":"login_falhou","mensagem":"Não foi possível autenticar. Verifique os dados.","estado":"PA","documento":"025.092.642-30"}},"estado_invalido":{"summary":"Estado não suportado","value":{"sucesso":false,"codigo":"estado_invalido","mensagem":"Estado inválido. Use: AL, AP, MA, PA, PI"}},"timeout":{"summary":"Tempo excedido","value":{"sucesso":false,"codigo":"timeout","mensagem":"Tempo excedido (90s).","estado":"PA","documento":"025.092.642-30"}}}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"tags":["Infra"],"summary":"Healthcheck do serviço","description":"Verifica se a API está no ar **e** se o Chromium (Playwright) está vivo/conectado.\n\nTenta **se auto-recuperar** primeiro (relança o Chromium se ele caiu). Só retorna\nHTTP **503** se o relaunch for impossível — aí o healthcheck do Docker/EasyPanel\nreinicia o container. Isso evita que o probe compita com o auto-relaunch por consulta:\nsem tráfego, o próprio healthcheck ressuscita o navegador. Retorna **200** quando ok.","operationId":"health_health_get","responses":{"200":{"description":"Status do serviço e se o navegador está realmente conectado.","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"ConsultaRequest":{"properties":{"estado":{"type":"string","title":"Estado","description":"Sigla ou nome do estado atendido pela Equatorial. Aceita sigla (`PA`, `pa`) ou nome com/sem acento (`Pará`, `para`).\n\n**Estados válidos (sigla → estado):**\n- `AL` → Alagoas\n- `AP` → Amapá\n- `MA` → Maranhão\n- `PA` → Pará\n- `PI` → Piauí","examples":["PA"]},"documento":{"type":"string","title":"Documento","description":"CPF ou CNPJ do titular da conta de energia. Os mesmos dados que o próprio titular usaria para entrar no portal. Pode enviar com ou sem máscara (`003.920.472-33` ou `00392047233`).","examples":["003.920.472-33"]},"nascimento":{"type":"string","title":"Nascimento","description":"Data de nascimento do titular no formato **dd/mm/aaaa**.","examples":["07/06/1991"]},"rg":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Rg","description":"RG do titular. **Opcional** — informe apenas se uma consulta anterior tiver retornado `codigo: \"rg_obrigatorio\"`. O portal só pede RG esporadicamente (em repetições pelo mesmo IP/dispositivo).","examples":["1234567"]}},"type":"object","required":["estado","documento","nascimento"],"title":"ConsultaRequest","examples":[{"documento":"003.920.472-33","estado":"PA","nascimento":"07/06/1991"}]},"ConsultaResponse":{"properties":{"sucesso":{"type":"boolean","title":"Sucesso","description":"`true` se a consulta retornou faturas; `false` em qualquer condição de erro/bloqueio."},"codigo":{"type":"string","title":"Codigo","description":"Código do resultado. Sempre presente (a API nunca lança exceção ao cliente):\n\n- `ok` — consulta concluída, veja `contas`.\n- `rg_obrigatorio` — o portal exigiu RG; reenvie incluindo o campo `rg`.\n- `login_falhou` — dados de acesso recusados ou anti-bot bloqueou após os retries.\n- `timeout` — excedeu `TIMEOUT_CONSULTA` segundos.\n- `estado_invalido` — sigla/nome de estado não suportado.\n- `erro` — falha inesperada (veja `mensagem`).","default":"ok","examples":["ok"]},"mensagem":{"type":"string","title":"Mensagem","description":"Detalhe legível, preenchido principalmente em casos de erro. Já vem com orientação do que fazer.","default":""},"motivo":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Motivo","description":"Classificação técnica quando há erro: `dados_rejeitados` (CPF/nascimento recusados ou anti-bot), `bloqueio_antibot` (Imperva barrou), `sem_resposta` (portal não respondeu), `timeout`, `excecao`, `rg_obrigatorio`. `null` em sucesso.","examples":["dados_rejeitados"]},"tentativas":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Tentativas","description":"Quantas tentativas de login foram feitas nesta consulta.","examples":[2]},"duracao_s":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Duracao S","description":"Duração total da consulta em segundos (inclui espera em fila, se houver).","examples":[24.3]},"estado":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Estado","description":"Sigla canônica do estado consultado.","examples":["PA"]},"documento":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Documento","description":"Documento ecoado da requisição.","examples":["003.920.472-33"]},"titular":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Titular","description":"Nome do titular conforme exibido no portal.","examples":["Valeria Do Nascimento Borges"]},"consultado_em":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Consultado Em","description":"Timestamp UTC (ISO 8601) do momento da consulta.","examples":["2026-06-27T20:46:12+00:00"]},"total_faturas":{"type":"integer","title":"Total Faturas","description":"Quantidade total de faturas em aberto somando todas as contas.","default":0,"examples":[1]},"total_em_aberto":{"type":"number","title":"Total Em Aberto","description":"Soma geral em aberto de todas as contas.","default":0.0,"examples":[96.79]},"contas":{"items":{"$ref":"#/components/schemas/Conta"},"type":"array","title":"Contas","description":"Lista de contas do titular, cada uma com suas faturas em aberto.","default":[]}},"type":"object","required":["sucesso"],"title":"ConsultaResponse"},"Conta":{"properties":{"indice":{"type":"integer","title":"Indice","description":"Índice sequencial da conta (1, 2, ...). Um titular pode ter várias contas/unidades.","examples":[1]},"contrato":{"type":"string","title":"Contrato","description":"Número do contrato/conta. Só disponível quando o titular tem mais de uma conta (tela de seleção); vazio para conta única.","default":"","examples":["003016849234"]},"endereco":{"type":"string","title":"Endereco","description":"Endereço da unidade consumidora (logradouro e bairro).","default":"","examples":["Governador Magalhães Barata, São Brás"]},"faturas":{"items":{"$ref":"#/components/schemas/Fatura"},"type":"array","title":"Faturas","description":"Faturas em aberto desta conta."},"total_em_aberto":{"type":"number","title":"Total Em Aberto","description":"Soma dos valores em aberto desta conta.","examples":[96.79]}},"type":"object","required":["indice","faturas","total_em_aberto"],"title":"Conta"},"Fatura":{"properties":{"status":{"type":"string","title":"Status","description":"Situação da fatura no portal (ex.: `Vencida`, `A vencer`).","default":"","examples":["Vencida"]},"referencia":{"type":"string","title":"Referencia","description":"Mês de referência da fatura (competência).","default":"","examples":["2026/06"]},"vencimento":{"type":"string","title":"Vencimento","description":"Data de vencimento (dd/mm/aaaa).","default":"","examples":["26/06/2026"]},"valor":{"type":"string","title":"Valor","description":"Valor da fatura como exibido no portal (texto).","default":"","examples":["R$ 96,79"]},"valor_num":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Valor Num","description":"Mesmo valor convertido para número (útil para somas/cálculos).","examples":[96.79]}},"type":"object","title":"Fatura"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}},"tags":[{"name":"Consulta","description":"Consulta de faturas em aberto por titular."},{"name":"Infra","description":"Verificação de saúde do serviço e do navegador."}]}