> ## Documentation Index
> Fetch the complete documentation index at: https://developers.pontua.com.br/llms.txt
> Use this file to discover all available pages before exploring further.

# Relatórios

> Geração assíncrona de relatórios oficiais (AFD, AEJ, espelho de ponto, banco de horas, horas extras, eventos folha) com polling e download. Conformidade Portaria 671.

A tag **Relatório** é frequentemente o **principal driver** de quem
integra com o Pontua: contadores, escritórios e ERPs precisam puxar
dados consolidados em formatos específicos para folha de pagamento,
fiscalização do MTE, ou auditoria interna.

## Como funciona

Geração de relatório é **assíncrona em três etapas** — não tente fazer
em uma chamada só:

```
1. POST /relatorio/<tipo>           ← dispara geração
   ↓ retorna { relatorioId, status: "PROCESSANDO" }

2. GET /relatorio/{relatorioId}     ← polling até concluir
   ↓ status muda para "CONCLUIDO" ou "ERRO"

3. POST /relatorio/download         ← obtém URL ou base64
   ↓ retorna conteúdo final
```

Por que assíncrono? Relatórios consolidam dezenas de milhares de
registros, calculam horas extras com regras CLT complexas, e geram
arquivos com assinatura digital — operação CPU-intensiva que não
cabe em um request HTTP síncrono.

## Tipos de relatório

<AccordionGroup>
  <Accordion title="AFD — Arquivo Fonte de Dados (Portaria 671)">
    `POST /relatorio/afd`

    **O que é:** o arquivo bruto exigido pelo MTE em fiscalização. Contém
    **todas as marcações** brutas do REP-P do período, com NSR sequencial,
    formato `ISO 8859-1`, estrutura tipo 1/3/99.

    **Quando usar:**

    * Fiscalização do MTE (agente fiscal solicita "AFD do período X")
    * Auditoria interna ou de terceiro
    * Anexar em processo trabalhista

    **Saída:** arquivo `.txt` assinado digitalmente (CAdES detached `.p7s`
    junto). Encoding **ISO 8859-1**, não UTF-8 — abrir em editor que
    respeite encoding.
  </Accordion>

  <Accordion title="AEJ — Arquivo Eletrônico de Jornada">
    `POST /relatorio/aej`

    **O que é:** versão consolidada do AFD que agrega marcações em
    **jornadas** (entrada/saída pareadas) com cálculo de horas
    trabalhadas, ausências, horas extras. Estrutura tipo 01-08 + 99
    conforme Portaria 671.

    **Quando usar:**

    * Auditoria mais legível que AFD bruto
    * Compliance específico que exige jornada calculada (não só batidas)
    * Anexar em fechamento mensal

    **Saída:** `.txt` assinado, encoding `ISO 8859-1`.
  </Accordion>

  <Accordion title="Espelho de Ponto">
    `POST /relatorio/espelho-ponto`

    **O que é:** PDF formatado com a jornada **individual** ou da equipe
    no período. Mostra batidas, jornada esperada, horas extras, atrasos —
    ideal para conferência.

    **Quando usar:**

    * Conferência mensal antes de fechar folha
    * Anexar em recibo de pagamento
    * Validação assinada pelo colaborador (PAdES embed)

    **Saída:** PDF assinado.
  </Accordion>

  <Accordion title="Banco de Horas">
    `POST /relatorio/banco-horas`

    **O que é:** saldos e movimentações de banco de horas no período.
    Mostra entradas (horas extras acumuladas), saídas (compensações,
    abonos), saldo final, e prazo de prescrição (caducidade) por
    colaborador.

    **Quando usar:**

    * Conferência de saldos antes de quitação em folha
    * Auditoria de banco de horas vencido (Art. 59 CLT — Lei 13.467/2017)
    * Relatório para acordo coletivo de banco de horas

    **Saída:** PDF ou CSV.
  </Accordion>

  <Accordion title="Horas Extras">
    `POST /relatorio/horas-extras`

    **O que é:** consolidado de horas extras por colaborador no período,
    com percentuais aplicados (50% dia útil, 100% domingo/feriado) e
    valores estimados.

    **Quando usar:**

    * Folha mensal — entrada de eventos de hora extra
    * Comparação com estimativa orçamentária
    * Relatório executivo de custo de HE

    **Saída:** PDF ou CSV.
  </Accordion>

  <Accordion title="Horas Extras Analítico (com Adicional Noturno)">
    `POST /relatorio/horas-extras-an`

    **O que é:** versão **detalhada** do anterior incluindo:

    * Adicional noturno (CLT Art. 73 — período 22h-5h, hora ficta 52'30", coeficiente 1.142857)
    * Detalhamento por dia, jornada, faixa
    * Memória de cálculo

    **Quando usar:**

    * Auditoria fina de cálculos
    * Validação em processo trabalhista
    * Justificativa de divergências entre Pontua e folha externa

    **Saída:** CSV (estrutura tabular para análise).
  </Accordion>

  <Accordion title="Localizações (LGPD)">
    `POST /relatorio/localizacoes`

    **O que é:** auditoria GPS das batidas — coordenadas, distância do
    cerco, dispositivo usado.

    <Warning>
      **LGPD pesado.** Localização é dado pessoal sensível. Gerar esse
      relatório requer base legal documentada (acordo trabalhista,
      consentimento explícito). Não exporte para uso amplo.
    </Warning>

    **Quando usar:**

    * Auditoria de fraude pontual (suspeita de batida fora do trabalho)
    * Resposta a solicitação do MTE com base em denúncia
    * Atendimento a Art. 18 LGPD do colaborador (acesso a dados próprios)
  </Accordion>

  <Accordion title="Faltas, Atrasos e Antecipações">
    `POST /relatorio/faltas-atrasos-antecipacoes`

    **O que é:** consolidado de irregularidades de presença por
    colaborador — quantidade de faltas, atrasos, antecipações de saída,
    com totais em horas.

    **Quando usar:**

    * Folha — descontos por falta/atraso
    * Relatório disciplinar ou advertência
    * BI de absenteísmo

    **Saída:** PDF ou CSV.
  </Accordion>

  <Accordion title="Eventos para Folha de Pagamento">
    `POST /relatorio/eventos-folha-pagamento`

    **O que é:** arquivo TXT no **layout específico do seu sistema de
    folha** (configurado previamente em [Folha de Pagamento](/referencia/folha-de-pagamento)).
    Contém eventos consolidados (proventos, descontos) prontos para
    importação.

    **Quando usar:**

    * Sync automático mensal Pontua → folha externa
    * **Top use case** para contadores e ERPs

    **Saída:** TXT no layout pré-cadastrado. Encoding e separadores
    seguem o layout escolhido.

    Ver guia [Puxar folha do mês](/guias-praticas/puxar-folha-do-mes).
  </Accordion>
</AccordionGroup>

## Endpoints

### Geração e gestão

| Método | Rota                                     | Descrição                                    |
| ------ | ---------------------------------------- | -------------------------------------------- |
| POST   | `/relatorio/afd`                         | Gera AFD Portaria 671                        |
| POST   | `/relatorio/aej`                         | Gera AEJ                                     |
| POST   | `/relatorio/espelho-ponto`               | Gera espelho de ponto                        |
| POST   | `/relatorio/banco-horas`                 | Gera relatório de banco de horas             |
| POST   | `/relatorio/horas-extras`                | Gera relatório de horas extras               |
| POST   | `/relatorio/horas-extras-an`             | Versão analítica de HE com adicional noturno |
| POST   | `/relatorio/localizacoes`                | Auditoria GPS (LGPD)                         |
| POST   | `/relatorio/faltas-atrasos-antecipacoes` | Faltas, atrasos, antecipações                |
| POST   | `/relatorio/eventos-folha-pagamento`     | Eventos consolidados para folha              |

### Listagem, status e download

| Método | Rota                       | Descrição                              |
| ------ | -------------------------- | -------------------------------------- |
| GET    | `/relatorio`               | Lista relatórios gerados (com filtros) |
| GET    | `/relatorio/{relatorioId}` | Status + metadata de um relatório      |
| POST   | `/relatorio/download`      | Obter URL/conteúdo do download         |
| DELETE | `/relatorio/{relatorioId}` | Remove (não-recuperável)               |

Schema completo + try-it em [Referência da API](/api-reference#tag/Relatório).

## Padrão geral de polling

```javascript theme={null}
async function gerarRelatorio(token, tipo, params, opts = {}) {
  const headers = {
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json',
  }

  // 1. Dispara geração
  const dispatchResp = await fetch(
    `https://api.pontua.com.br/relatorio/${tipo}`,
    { method: 'POST', headers, body: JSON.stringify(params) },
  )
  if (!dispatchResp.ok) throw new Error(await dispatchResp.text())
  const { relatorioId } = await dispatchResp.json()

  // 2. Polling com backoff exponencial até concluir
  const maxTentativas = opts.maxTentativas ?? 60
  for (let i = 0; i < maxTentativas; i++) {
    const status = await fetch(
      `https://api.pontua.com.br/relatorio/${relatorioId}`,
      { headers },
    ).then((r) => r.json())

    if (status.status === 'CONCLUIDO') break
    if (status.status === 'ERRO') {
      throw new Error(`Geração falhou: ${status.mensagemErro || 'desconhecido'}`)
    }

    // 5s, 10s, 20s, 40s, capped em 60s
    const delayMs = Math.min(5000 * Math.pow(1.5, i), 60000)
    await new Promise((r) => setTimeout(r, delayMs))
  }

  // 3. Baixa
  const downloadResp = await fetch(
    'https://api.pontua.com.br/relatorio/download',
    { method: 'POST', headers, body: JSON.stringify({ relatorioId }) },
  )
  return downloadResp.json()
}

// Exemplo de uso
const url = await gerarRelatorio(TOKEN, 'banco-horas', {
  dataInicio: '2026-04-01',
  dataFim: '2026-04-30',
  formato: 'CSV',
})
```

## Boas práticas

<CardGroup cols={2}>
  <Card icon="clock" title="Não bloqueie thread esperando">
    Polling síncrono em loop é antipattern. Salve o `relatorioId` em
    fila/DB e processe em worker separado. Para datasets grandes, geração
    pode levar minutos.
  </Card>

  <Card icon="repeat" title="Cache do relatorioId pra retry de download">
    Se a etapa 3 (download) falhar, **não regenere o relatório** —
    use o mesmo `relatorioId` para tentar baixar novamente. Geração custa
    caro (CPU + I/O no banco + assinatura digital).
  </Card>

  <Card icon="filter" title="Filtre o máximo possível na geração">
    Não gere "AEJ do ano todo de toda a empresa" se você só precisa de
    um departamento de um mês. Filtros antes de gerar = relatórios
    menores + mais rápidos + menos pressão no banco.
  </Card>

  <Card icon="vault" title="Persista os arquivos do seu lado">
    URLs S3 do `download` têm TTL configurado. Para auditoria histórica
    (5 anos para registros de ponto, 10 anos para folha), baixe
    imediatamente e guarde em storage próprio.
  </Card>
</CardGroup>

## Gotchas conhecidos

<Warning title="AFD/AEJ usam encoding ISO 8859-1, não UTF-8">
  Esses arquivos seguem a especificação da Portaria 671 que exige
  `ISO 8859-1` (latin1). Se sua aplicação espera UTF-8, vai ver
  caracteres acentuados quebrados ("ç", "ã" como `?`). Sempre decode
  como `latin1`/`iso-8859-1` ao processar.
</Warning>

<Warning title="DELETE de relatório é irreversível">
  `DELETE /relatorio/{id}` apaga o arquivo + metadata. Para auditoria
  Portaria 671 (Art. 98 — retenção 5 anos), evite deletar e prefira
  filtrar nas listagens.
</Warning>

<Warning title="Relatório de período aberto pode mudar depois">
  Se você gera relatório de mês ainda **não fechado**, ajustes
  posteriores no período podem fazer um relatório futuro divergir.
  Para snapshot **imutável**, gere após `POST /fechamento` concluir —
  ver [Fechamento](/referencia/fechamento).
</Warning>

<Warning title="Eventos de folha exigem layout pré-cadastrado">
  `POST /relatorio/eventos-folha-pagamento` falha se a UN não tem
  layout configurado. Cadastre o layout primeiro em
  [Folha de Pagamento](/referencia/folha-de-pagamento) (via dashboard
  ou API se exposta para o caso).
</Warning>

## Veja também

* [Puxar folha do mês](/guias-praticas/puxar-folha-do-mes) — fluxo completo de export
* [Gerar relatório de banco de horas](/guias-praticas/relatorio-banco-horas) — polling + download
* [Idempotência](/conceitos/idempotencia) — evitar dispatches duplicados em retry
* [Frequência](/referencia/frequencia) — agregados em tempo real (alternativa pra casos simples)
* [Banco de Horas](/referencia/banco-horas) — saldos consolidados por ciclo
* [Fechamento](/referencia/fechamento) — quando relatórios ficam "definitivos"
