Skip to main content
Registro de ponto é o evento de marcação de jornada de um colaborador — entrada, saída, intervalos. É a fonte primária para todo cálculo de frequência, horas extras, banco de horas e folha de pagamento da plataforma. A API permite que sistemas externos (REPs customizados homologados, apps próprios, integradores de jornada) registrem batidas, importem arquivos AFD pré-existentes e consultem históricos.

Contexto regulatório

A Pontua atua como REP-P (Registrador Eletrônico de Ponto via Programa) homologado pelo INPI sob a Portaria MTP 671/2021 e Portaria 1.486/2022. Isso traz obrigações inegociáveis para qualquer integração que manipula registros:

NSR — Número Sequencial de Registro

Cada batida recebe um NSR sequencial gerado pelo Pontua, nunca pelo cliente. Esse número entra no AFD/AEJ e nos comprovantes assinados. Sequência inválida (gaps, duplicatas) configura irregularidade.

Comprovante de registro

Para cada batida registrada, o colaborador tem direito a um comprovante assinado digitalmente (PAdES embed). O comprovante contém o NSR + hash SHA-256 + metadata INPI.

AFD e AEJ assinados

Arquivos exportados (AFD, AEJ) recebem assinatura digital CAdES detached (.p7s). Os arquivos têm encoding ISO 8859-1 e estrutura fixa por tipo (1 cabeçalho, 3 marcações, 99 trailer no AFD).

Soft-delete obrigatório

Registros nunca podem ser fisicamente removidos. Correções via API geram novo registro com flag de ajuste + motivo + auditoria. O histórico original é preservado por 5 anos (Art. 98).

Origens de registro

Cada registro carrega o campo origem indicando como foi capturado. A integração de cliente externo tipicamente registra apenas API ou AFD:
OrigemSignificadoAcessível via API?
APPMobile app oficial PontuaNão (interno)
WEBPortal de marcação web PontuaNão (interno)
REPRelógio de ponto físico homologadoLimitado ao token de integração específico
APIIntegração externa via RESTPOST /registro-ponto
AFDImportação de arquivo AFDPOST /registro-ponto/afd
AJUSTEAjuste manual aprovadoVia fluxo de Ajustes (não direto)

Endpoints públicos

Registrar batidas

POST /registro-ponto — Registra uma batida pontual.Quando usar:
  • REP customizado próprio (cliente que tem hardware homologado)
  • App de RH/onboarding que precisa registrar entrada manualmente
  • Sistema de portaria/controle de acesso integrado
Quando NÃO usar:
  • Sincronizar batidas históricas de outro sistema (use AFD em vez)
  • Importar grandes lotes de uma só vez (use AFD)
  • Eventos do app Pontua oficial (já passa por outra rota interna)
A jornada esperada do colaborador (turno) é validada no momento. Batidas fora da janela de tolerância podem cair em status PENDENTE aguardando aprovação de gestor. Veja Frequência.

Consultar registros

GET /registro-ponto — Lista registros com filtros.Filtros típicos: colaboradorId, dataInicio, dataFim, status, origem, departamentoId. Use paginação pagina + limite para iterar grandes volumes — ver Paginação.Para sync incremental com seu sistema, salve um cursor de timestamp e filtre por data crescente — ver Webhooks (polling).

Modelo de dados (campos chave)

{
  id: string                          // UUID Pontua
  nsr: number                         // Número Sequencial de Registro (Portaria 671)
  colaboradorId: string
  dataHora: string                    // ISO 8601 com timezone (BRT padrão)
  origem: "APP" | "REP" | "WEB" | "API" | "AFD" | "AJUSTE"
  status: "VALIDO" | "PENDENTE" | "REJEITADO"
  hash: string                        // SHA-256 do registro (verifiable)
  // ... demais campos no spec OpenAPI
}
CampoSignificado
nsrSequencial gerado pelo Pontua ao gravar. Único e crescente por UN. Aparece no AFD/AEJ/comprovantes.
dataHoraMomento exato da batida em ISO 8601. Use timezone BRT (-03:00) — registros sem timezone são interpretados como BRT por default.
origemComo o registro entrou no sistema. Sua API key registra como API.
statusVALIDO é o caso normal. PENDENTE aguarda aprovação. REJEITADO quando há violação clara (ex: batida fora do cerco geográfico).
hashSHA-256 do conteúdo, cacheado no servidor e expresso no comprovante. Permite verificação offline de integridade.

Fluxos típicos

Registrar batida em REP customizado

// Hardware próprio detectou marcação biométrica → envia para Pontua
async function registrarBatidaRep(token, dadosBatida) {
  const resp = await fetch('https://api.pontua.com.br/registro-ponto', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      colaboradorId: dadosBatida.colaboradorId,
      dataHora: dadosBatida.timestamp,  // já com timezone
      // demais campos opcionais (localização, etc) conforme spec
    }),
  })

  if (!resp.ok) {
    const erro = await resp.json()
    throw new Error(`${erro.service}: ${erro.message}`)
  }

  const registro = await resp.json()
  console.log(`NSR ${registro.nsr} gerado para ${dadosBatida.colaboradorId}`)
  return registro
}

Sync incremental de batidas para BI

async function syncIncrementalBatidas(token, desde) {
  let pagina = 0
  const resultados = []

  while (true) {
    const params = new URLSearchParams({
      pagina: String(pagina),
      limite: '100',
      dataInicio: desde,  // ISO 8601 — cursor incremental
    })

    const resp = await fetch(
      `https://api.pontua.com.br/registro-ponto?${params}`,
      { headers: { Authorization: `Bearer ${token}` } },
    )
    const { resultados: lote, totalRegistros } = await resp.json()
    resultados.push(...lote)

    if ((pagina + 1) * 100 >= totalRegistros) break
    pagina++
  }

  // Salvar cursor para próxima execução
  if (resultados.length > 0) {
    const ultimaBatida = resultados[resultados.length - 1]
    await storage.set('pontua.ultimo_sync_batidas', ultimaBatida.dataHora)
  }

  return resultados
}

Gerar comprovantes mensais

async function gerarComprovantesMes(token, colaboradorId, mes) {
  const resp = await fetch(
    'https://api.pontua.com.br/registro-ponto/recibo',
    {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${token}`,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        colaboradorId,
        dataInicio: `${mes}-01`,
        dataFim: `${mes}-31`,  // ou último dia do mês exato
      }),
    },
  )

  // Resposta inclui URL S3 do PDF assinado (PAdES)
  const { url } = await resp.json()
  return url
}

Gotchas conhecidos

Não tente enviar nsr no payload de POST /registro-ponto — é ignorado ou rejeitado. O backend gera sequencial conforme Art. 80 da Portaria 671. Misturar fontes de NSR é violação regulatória.
Sempre envie dataHora com offset explícito (ex: 2026-04-26T08:30:00-03:00). Strings sem timezone são interpretadas como BRT, mas isso pode falhar em horário de verão (ainda que abolido em 2019, alguns ambientes legados têm problemas). Para máxima portabilidade: sempre com offset.
Se o período da dataHora está em fechamento concluído, o registro é rejeitado ou cai em fluxo de ajuste com aprovação. Verifique o status do fechamento antes de bulk-import histórico — ver Fechamento.
São dados pessoais sensíveis. Sua integração deve:
  • Tratar com base legal explícita (consentimento ou execução de contrato)
  • Não trafegar fora do Brasil sem AIPD (Avaliação de Impacto)
  • Implementar política de retenção curta (URLs S3 com TTL no seu lado também)
GET /registro-ponto/gestao/dashboard, GET /registro-ponto/gestao/minha-equipe, GET /registro-ponto/frequencias e variantes estão deprecated. Use a tag Frequency para agregados — ver Frequência.

Endpoints expostos publicamente

MétodoRotaDescrição
GET/registro-pontoLista com filtros
GET/registro-ponto/ultimosÚltimas batidas de um colaborador
GET/registro-ponto/localizacoesCoordenadas GPS dos registros
GET/registro-ponto/fotosURLs S3 das fotos (com expiração)
POST/registro-pontoRegistrar batida individual via API
POST/registro-ponto/afdImportar arquivo AFD em massa
POST/registro-ponto/reciboGerar comprovantes PDF assinados
Schema completo + try-it em Referência da API.

Veja também