Skip to main content
A tag Relatório é frequentemente o principal driver de quem integra com a Pontua — contadores, escritórios e ERPs precisam puxar dados consolidados em formatos específicos para folha, fiscalização ou auditoria.

Como funciona

Geração de relatório é assíncrona em três etapas:
1. POST /relatorio/<tipo>           ← dispara geração
   ↓ retorna identificador

2. GET /relatorio/{relatorioId}     ← polling até concluir

3. POST /relatorio/download         ← baixa o arquivo
Os campos exatos de request/response (parâmetros aceitos, formato da resposta de status) estão em Referência da API.

Endpoints principais

Geração

MétodoRotaTipo de relatório
POST/relatorio/afdAFD (Portaria 671)
POST/relatorio/aejAEJ (Arquivo Eletrônico de Jornada)
POST/relatorio/espelho-pontoEspelho de Ponto
POST/relatorio/banco-horasBanco de Horas
POST/relatorio/horas-extrasHoras Extras
POST/relatorio/horas-extras-anHoras Extras (Analítico)
POST/relatorio/localizacoesAuditoria GPS
POST/relatorio/faltas-atrasos-antecipacoesFaltas, Atrasos, Antecipações
POST/relatorio/eventos-folha-pagamentoEventos para folha de pagamento

Gestão

MétodoRotaDescrição
GET/relatorioLista relatórios gerados (com filtros)
GET/relatorio/{relatorioId}Status + metadata de um relatório
POST/relatorio/downloadObter URL/conteúdo de download
DELETE/relatorio/{relatorioId}Remove (não-recuperável)
Schema completo com try-it em Referência da API.

Padrão geral de polling

async function gerarERelatorioGenerico(tipo, params) {
  const TOKEN = process.env.PONTUA_API_TOKEN
  const headers = {
    Authorization: `Bearer ${TOKEN}`,
    'Content-Type': 'application/json',
  }

  // 1. Dispara geração — campos do body variam por tipo (ver Referência)
  const respostaGeracao = await fetch(
    `https://api.pontua.com.br/relatorio/${tipo}`,
    { method: 'POST', headers, body: JSON.stringify(params) },
  )
  const { relatorioId } = await respostaGeracao.json()

  // 2. Polling com backoff
  for (let attempt = 0; attempt < 60; attempt++) {
    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}`)
    }

    // 5s, 10s, 20s, capped em 60s. Total max ~30 min.
    const delay = Math.min(5000 * Math.pow(1.5, attempt), 60000)
    await new Promise((r) => setTimeout(r, delay))
  }

  // 3. Baixa
  const download = await fetch('https://api.pontua.com.br/relatorio/download', {
    method: 'POST',
    headers,
    body: JSON.stringify({ relatorioId }),
  })
  return download.json()
}
Os campos exatos do body (status enum, formato de retorno do download) podem variar por endpoint e estão documentados na Referência. Cheque o schema antes de implementar pra cada tipo.

Boas práticas

Não bloqueie a thread esperando

Polling síncrono em loop é antipattern. Salve o relatorioId em fila/DB, processe em worker separado quando concluir.

Cache do `relatorioId` para retry

Se a etapa de download falhar, não regenere o relatório — use o mesmo relatorioId para tentar baixar de novo. Geração custa caro (CPU + I/O no banco).

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.

Veja também

  • Idempotência — evitar dispatches duplicados em retry
  • Frequência — agregados diários (alternativa para casos simples)