Tratamento do retorno da Receita Federal
API do validador Educacenso (app censo) para outro sistema (ex.: o educacao)
tratar o retorno do INEP e obter as divergências da Receita Federal (o
dado enviado e o dado correto que o INEP informou).
Escopo intencionalmente estreito: estas rotas não validam o arquivo inteiro. Elas olham somente as mensagens do retorno que citam explicitamente a Receita Federal — as que trazem o conteúdo no formato
valor enviado -- valor correto.
Duas rotas
| Rota | Envia | Recebe | Quando usar |
|---|---|---|---|
POST /api/divergencias-rf ⭐ | só o retorno (JSON/XLSX) | divergências cruas por campo, com codigo_na_escola | Recomendada. Dispensa o TXT; a pessoa é casada pelo codigo_na_escola (estável entre versões). É o fluxo usado pelo educacao. |
POST /api/retorno-rf | retorno + txt | uma pessoa por registro, já mesclada | Variante que monta o registro completo mesclando com o TXT. Requer o mesmo TXT enviado ao INEP. |
Por que a
divergencias-rfé preferível. Aretorno-rfcasa a pessoa pela linha do TXT — que muda se o aviso for importado noutra versão do arquivo, gerando divergências erradas. Adivergencias-rfusa ocodigo_na_escola(coluna do próprio retorno do INEP), que é o identificador estável da pessoa na origem (noeducacao, opessoa_id).
POST /api/divergencias-rf (recomendada)
Recebe apenas o retorno do INEP e devolve as divergências da Receita
Federal cruas — o valor enviado e o correto, por campo, com o
codigo_na_escola para o consumidor localizar a pessoa.
- Base URL / Auth / Content-Type: iguais aos da
/api/retorno-rf(ver abaixo, incluindo o aviso do Cloudflare Access).
Parâmetros (form-data)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
retorno | file | sim | Retorno do INEP em .json ou .xlsx. Não envie o TXT. |
Resposta
200 OK, application/json:
{
"divergencias": [
{
"codigo_na_escola": "328229",
"linha": "28",
"campo": "Data de nascimento",
"enviado": "07/02/1960",
"correto": "07/03/1960",
"is_filiacao": false,
"chave": "data_nascimento"
}
]
}
| Campo | Significado |
|---|---|
codigo_na_escola | Coluna "Código na Escola" do retorno — o identificador estável da pessoa na origem (no educacao, é o pessoa_id/Person). É a chave para localizar a pessoa, e não a linha. |
linha | Linha do TXT (registro 30). Só referência — não use para casar a pessoa. |
campo | Nome do campo como o INEP rotulou no retorno. |
enviado | Valor que você mandou (lado esquerdo de enviado -- correto). |
correto | Valor da base da Receita (lado direito). |
is_filiacao | true quando a divergência é de filiação (nome da mãe/pai). |
chave | Coluna de destino no consumidor: cpf/nome/data_nascimento/inep para os campos comuns; nome_mae/nome_pai para filiação (o INEP costuma rotular filiação como "Identificação única (Inep)" — a API resolve mãe×pai pela mensagem); null para campo não mapeado. |
Exemplo — cURL
curl -sS -X POST \
-H "x-api-key: $API_KEY" \
-F "retorno=@Retorno_INEP.xlsx" \
https://validador-educacenso-27c68db3d752.herokuapp.com/api/divergencias-rf
Integração no
educacao. O botão "Tratar retorno RF" sobe só o retorno do INEP; a actionBuscarRetornoRfchama esta rota e carimba as colunas*_rfdaPersonlocalizada porcodigo_na_escola(viachave→ coluna), que então aparece em Divergências no Educacenso.
POST /api/retorno-rf (mescla com o TXT)
Envia o retorno do INEP + o TXT do Educacenso e recebe, já mescladas por pessoa, as divergências da Receita Federal.
Endpoint
POST /api/retorno-rf
- Base URL (produção):
https://validador-educacenso-27c68db3d752.herokuapp.com(URL direta do Heroku — ver aviso sobre Cloudflare abaixo). - Autenticação: header
x-api-key: <API_KEY>(token compartilhado). - Content-Type:
multipart/form-data.
Atenção — Cloudflare Access. O domínio bonito
https://validador-educacenso.appolus.com.brestá atrás do Cloudflare Access na borda, que redireciona/api/*para uma tela de login (HTTP 302) — ou seja, um sistema externo não consegue chamá-lo por ali. Duas opções:
- Usar a URL direta do Heroku (recomendado agora):
https://validador-educacenso-27c68db3d752.herokuapp.com/api/retorno-rf. O app libera/api/*no seu próprio guard de Access e exige só o token.- Liberar
/api/*no Cloudflare Access (bypass policy ou service token) para poder usar o domínioappolus.com.br. Isso é configuração de infra, fora do código.
Parâmetros (form-data)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
retorno | file | sim | Retorno do INEP em .json ou .xlsx. |
txt | file | sim | TXT do Educacenso (o mesmo arquivo enviado ao INEP). É de onde saem nome_mae, inep e os campos sem divergência. |
Header
| Header | Valor |
|---|---|
x-api-key | O token configurado na env API_KEY do app censo. |
Resposta
200 OK, application/json:
{
"pessoas": [
{
"cpf": "11122233344",
"nome": "FULANO DE TAL DA SILVA",
"data_nascimento": "15/03/2010",
"nome_mae": "BELTRANA DE TAL DA SILVA",
"inep": "123456789012"
}
]
}
- Uma entrada por pessoa (cada registro 30 do TXT) que tenha ao menos uma divergência da Receita Federal.
data_nascimentono formatodd/mm/yyyy(o mesmo do TXT/retorno).
Regra de preenchimento de cada campo
Para cada campo o valor é o que consta no TXT, exceto quando aquele campo tem
uma divergência da Receita Federal — aí usa-se o valor correto (lado direito
de enviado -- correto). As correções de várias linhas do retorno para a mesma
pessoa são mescladas num único objeto.
| Campo de saída | Origem |
|---|---|
cpf | TXT (campo 5) ou valor correto da RF se divergiu |
nome | TXT (campo 6) ou valor correto da RF se divergiu |
data_nascimento | TXT (campo 7) ou valor correto da RF se divergiu |
inep | TXT (campo 4) ou valor correto da RF se divergiu |
nome_mae | sempre TXT (campo 9 — Filiação 1). Nunca é corrigido. |
Exemplo: se um aluno tem 3 linhas no retorno (CPF divergente, data de nascimento divergente e INEP divergente), sai 1 objeto só, com esses três campos já com o valor correto e os demais (inclusive
nome_mae) com o valor original do TXT.
Como uma divergência da Receita é reconhecida
Uma mensagem do retorno entra no cálculo quando:
- É do registro 30 (pessoa física); e
- A mensagem cita "Receita Federal" (ex.: "O campo não está de acordo com a base da Receita Federal."); e
- O conteúdo do campo vem como
enviado -- correto(ex.:FULANO DE TAL DA SILVA OLIVEIRA -- FULANO DE TAL DA SILVA).
O campo corrigido é identificado pelo nome do campo informado no retorno
(Número do CPF → cpf, Nome completo → nome, Data de nascimento →
data_nascimento, Identificação única (Inep) → inep). Divergências de
filiação não corrigem nome_mae.
Erros
| HTTP | Quando | Corpo |
|---|---|---|
400 | Falta retorno ou txt, extensão inválida, ou arquivo ilegível | {"erro": "..."} |
401 | x-api-key ausente ou incorreto | {"erro": "Credencial inválida (header x-api-key)."} |
503 | App sem API_KEY configurada | {"erro": "API não configurada (defina a env API_KEY)."} |
Configuração (app censo)
Defina a env no Heroku:
heroku config:set API_KEY="<token-forte>" -a validador-educacenso
Sem API_KEY a rota responde 503 (fail-closed).
Exemplo — cURL
curl -sS -X POST \
-H "x-api-key: $API_KEY" \
-F "retorno=@Retorno_INEP.xlsx" \
-F "txt=@educacenso_escola.txt" \
https://validador-educacenso.appolus.com.br/api/retorno-rf
Exemplo — Ruby (Faraday, multipart)
conn = Faraday.new(url: base_url) { |f| f.request :multipart }
resp = conn.post("/api/retorno-rf") do |req|
req.headers["x-api-key"] = api_key
req.body = {
"retorno" => Faraday::Multipart::FilePart.new(retorno_io, "application/octet-stream", "retorno.xlsx"),
"txt" => Faraday::Multipart::FilePart.new(txt_io, "text/plain", "educacenso.txt"),
}
end
pessoas = JSON.parse(resp.body)["pessoas"]
Notas de implementação
- Código:
censo/retorno_rf.py—extrair_divergencias(cruas, só retorno) eextrair_pessoas(merge com TXT); rotasapi_divergencias_rfeapi_retorno_rfemapp.py. - Reaproveita o parser do retorno (
censo/retorno.py) e do TXT (censo/parser.py). - Testes:
tests/test_api_retorno_rf.py. - Consumidor no
educacao:app/actions/buscar_retorno_rf.rb(usa/api/divergencias-rf). - Limite de upload do app: 25 MB (
MAX_CONTENT_LENGTH).