Documentação da API
A API REST do PontoFácil permite integrar controle de ponto, folha de pagamento e dados de RH diretamente no seu ERP, sistema de folha ou qualquer plataforma interna. Todas as respostas são em JSON.
https://pontofacil.net.br/api
/auth/login) exigem autenticação via Bearer Token.
Formato padrão de resposta
// Sucesso {"success" :true ,"data" : { ... },"message" :"OK" }// Lista paginada {"success" :true ,"data" : [ ... ],"total" :150 ,"pagina" :1 ,"porPagina" :20 ,"totalPaginas" :8 }// Erro {"success" :false ,"error" :"CODIGO_DO_ERRO" ,"message" :"Descrição legível do erro." }
Autenticação
O PontoFácil usa JWT (JSON Web Token). Faça login para obter o token e inclua-o em todas as requisições seguintes no header Authorization.
Autentica o usuário e retorna um par de tokens (access + refresh).
{
"email" : "admin@suaempresa.com" ,
"senha" : "sua_senha"
}
{
"success" : true ,
"data" : {
"token" : "eyJhbGciOiJIUzI1NiIsInR..." , // válido por 15 min
"refresh_token" : "eyJhbGciOiJIUzI1NiIsInR..." , // válido por 7 dias
"usuario" : {
"id" : "uuid" ,
"nome" : "João Silva" ,
"email" : "admin@suaempresa.com" ,
"perfil" : "admin" ,
"empresa_id" : "uuid"
}
}
}
Usando o token
curl https://pontofacil.net.br/api/usuarios \ -H"Authorization: Bearer {SEU_TOKEN}" \ -H"Content-Type: application/json"
const res =await fetch('https://pontofacil.net.br/api/usuarios' , { headers: {'Authorization' :`Bearer ${token}` ,'Content-Type' :'application/json' } });const { data } =await res.json();
Renovar token
{ "refresh_token" : "eyJhbGci..." }
Erros & Códigos
| Código HTTP | error | Significado |
|---|---|---|
| 400 | DADOS_INCOMPLETOS | Campos obrigatórios faltando no body |
| 401 | NAO_AUTENTICADO | Token ausente, inválido ou expirado |
| 403 | SEM_PERMISSAO | Perfil do usuário não tem acesso a este recurso |
| 403 | MODULO_NAO_CONTRATADO | Recurso requer módulo não incluso no plano |
| 404 | NAO_ENCONTRADO | Registro não existe ou pertence a outra empresa |
| 422 | VALIDACAO_INVALIDA | Valor de campo com formato inválido |
| 429 | RATE_LIMIT | Muitas requisições — aguarde e tente novamente |
| 500 | ERRO_INTERNO | Erro interno do servidor |
Rate Limiting
| Endpoint | Limite | Janela |
|---|---|---|
| Geral (todos) | 200 req | 1 minuto por IP |
/auth/login | 10 req | 1 minuto por IP |
/auth/cadastro | 5 req | 1 minuto por IP |
Ao atingir o limite, a API retorna HTTP 429 com o header Retry-After.
Funcionários
Gerencie o cadastro de colaboradores. Requer perfil rh, gestor, admin ou super_admin.
Lista todos os funcionários da empresa com paginação.
| Query | Tipo | Obrig. | Descrição |
|---|---|---|---|
| page | integer | opcional | Página (padrão: 1) |
| limit | integer | opcional | Por página, máx 100 (padrão: 20) |
| busca | string | opcional | Filtra por nome, e-mail ou matrícula |
{
"success" : true ,
"data" : [
{
"id" : "uuid" ,
"nome" : "Maria Souza" ,
"email" : "maria@empresa.com" ,
"cpf" : "123.456.789-00" ,
"matricula" : "00042" ,
"cargo" : "Analista" ,
"departamento" : "TI" ,
"perfil" : "funcionario" ,
"ativo" : true ,
"facial_ativo" : true ,
"ultimo_login" : "2026-04-17T14:32:00Z" ,
"criado_em" : "2025-01-10T09:00:00Z"
}
],
"total" : 42 , "pagina" : 1 , "porPagina" : 20 , "totalPaginas" : 3
}
Retorna um funcionário específico, incluindo salário vigente.
Cria um novo funcionário. Requer perfil rh ou superior.
{
"nome" : "Carlos Lima" , // obrigatório
"email" : "carlos@empresa.com" , // obrigatório
"senha" : "Senha@123" , // obrigatório
"cpf" : "987.654.321-00" , // opcional
"matricula" : "00043" , // opcional
"cargo" : "Desenvolvedor" , // opcional
"departamento" : "Engenharia" , // opcional
"data_admissao" : "2026-04-01" , // opcional (YYYY-MM-DD)
"perfil" : "funcionario" , // funcionario | gestor | rh | admin
"pin" : "1234" // opcional — PIN de 4-6 dígitos
}
Registros de Ponto
Retorna o histórico de batidas de um funcionário. Gestores e RH podem consultar qualquer funcionário via usuario_id.
| Query | Tipo | Obrig. | Descrição |
|---|---|---|---|
| mes | string | opcional | Formato YYYY-MM (ex: 2026-04) |
| inicio | string | opcional | Data início YYYY-MM-DD |
| fim | string | opcional | Data fim YYYY-MM-DD |
| usuario_id | uuid | opcional | ID do funcionário (gestores+) |
{
"success" : true ,
"data" : [
{
"id" : "uuid" ,
"usuario_id" : "uuid" ,
"tipo" : "entrada" , // entrada | saida_almoco | retorno_almoco | saida
"data_hora" : "2026-04-18T08:02:14Z" ,
"metodo" : "facial" , // facial | pin | foto_senha | manual
"latitude" : -23.5505 ,
"longitude" : -46.6333 ,
"status" : "aprovado" , // aprovado | pendente_aprovacao | rejeitado
"justificativa" : null
}
]
}
Retorna as batidas do dia atual do usuário autenticado.
Retorna quem está presente agora (última batida do dia por funcionário).
Lista batidas aguardando aprovação do gestor. Requer perfil gestor+.
Apuração & Banco de Horas
Retorna o banco de horas mensal de um funcionário (saldo de horas extras/negativas por dia).
| Query | Tipo | Obrig. | Descrição |
|---|---|---|---|
| mes | string | opcional | YYYY-MM (padrão: mês atual) |
| usuario_id | uuid | opcional | Gestor/RH pode consultar outros |
{
"data" : [
{
"data" : "2026-04-07" ,
"horas_trabalhadas" : "08:12" ,
"horas_esperadas" : "08:00" ,
"saldo" : "+00:12" ,
"falta" : false ,
"feriado" : false
}
]
}
Calcula e retorna o resumo mensal (total de horas, saldo acumulado, faltas). Requer perfil rh+.
Folha de Pagamento
Requer módulo folha_pagamento e perfil rh ou superior.
Retorna a folha calculada de um funcionário para o mês.
{
"data" : {
"usuario_id" : "uuid" ,
"mes_referencia" : "2026-04" ,
"salario_base" : 3500.00 ,
"horas_extras_valor" : 280.50 ,
"faltas_valor" : 0.00 ,
"inss" : 385.00 ,
"irrf" : 0.00 ,
"fgts" : 308.84 ,
"liquido" : 3395.50 ,
"status" : "calculada" // calculada | fechada
}
}
Retorna a folha de todos os funcionários do mês.
| Query | Tipo | Obrig. | Descrição |
|---|---|---|---|
| mes | string | opcional | YYYY-MM (padrão: mês atual) |
Afastamentos
Controle de férias, atestados médicos, licenças e outros afastamentos. Requer perfil gestor ou superior.
| Query | Tipo | Obrig. | Descrição |
|---|---|---|---|
| usuario_id | uuid | opcional | Filtra por funcionário |
| tipo | string | opcional | ferias | medico | maternidade | ... |
| status | string | opcional | pendente | aprovado | rejeitado |
| mes | string | opcional | YYYY-MM |
{
"data" : [
{
"id" : "uuid" ,
"usuario_id" : "uuid" ,
"funcionario_nome" : "Ana Lima" ,
"tipo" : "ferias" ,
"inicio" : "2026-07-01" ,
"fim" : "2026-07-30" ,
"dias_corridos" : 30 ,
"status" : "aprovado" ,
"justificativa" : null
}
]
}
{
"usuario_id" : "uuid" , // obrigatório
"tipo" : "medico" , // obrigatório
"inicio" : "2026-04-20" , // obrigatório
"fim" : "2026-04-22" , // obrigatório
"justificativa" : "Consulta médica especialista" ,
"cid" : "J45" , // código CID (atestados)
"status" : "aprovado" // padrão: pendente
}
Relatórios
Espelho de ponto mensal de um funcionário (todas as batidas + apuração por dia). Módulo relatorios_basico.
| Query | Tipo | Obrig. | Descrição |
|---|---|---|---|
| usuario_id | uuid | obrig. | ID do funcionário |
| mes | string | obrig. | YYYY-MM |
Resumo do mês para toda a empresa (total de horas, faltas, atrasos por funcionário). Requer perfil rh+.
Log de auditoria de alterações no sistema. Módulo auditoria. Requer perfil rh+.
Relatório completo da folha de pagamento para exportação. Módulo folha_pagamento.
Guia de Integração — Passo a Passo
Este guia mostra, do zero, como integrar qualquer sistema externo (ERP, folha, BI, app próprio) com o PontoFácil. Siga os passos em ordem — cada um depende do anterior.
Passo 1 — Obter as credenciais de acesso
Você precisa de um usuário com perfil admin na empresa. Faça login para receber o token (JWT de acesso, válido 15 min) e o refresh_token (renova o acesso, válido 7 dias).
const axios =require ('axios' );async function login () {const { data } =await axios.post ('https://pontofacil.net.br/api/auth/login' , { email:'admin@suaempresa.com' , senha:'sua_senha_aqui' });const token = data.data.token;// JWT — use em toda requisição const refreshToken = data.data.refresh_token;// guarde para renovar depois return { token, refreshToken }; }// Saída: // { token: "eyJhbGci...", refreshToken: "eyJhbGci..." }
import requestsdef login (): res = requests.post ('https://pontofacil.net.br/api/auth/login' , json={'email' :'admin@suaempresa.com' ,'senha' :'sua_senha_aqui' }) dados = res.json()['data' ]return dados['token' ], dados['refresh_token' ] token, refresh_token =login ()
$response =file_get_contents ('https://pontofacil.net.br/api/auth/login' ,false ,stream_context_create (['http' => ['method' =>'POST' ,'header' =>'Content-Type: application/json' ,'content' =>json_encode (['email' =>'admin@suaempresa.com' ,'senha' =>'sua_senha_aqui' ]) ]]) );$data =json_decode ($response ,true )['data' ];$token =$data ['token' ];
POST /auth/refresh com o refresh_token para renová-lo sem precisar fazer login novamente. Veja o Passo 6.
Passo 2 — Autenticar todas as requisições
Inclua o token no header Authorization: Bearer <TOKEN> em todas as chamadas. Sem ele a API retorna HTTP 401.
const api = axios.create ({ baseURL:'https://pontofacil.net.br/api' , headers: {'Authorization' :`Bearer ${token}` } });// Agora use `api` para todas as chamadas: const funcionarios =await api.get ('/usuarios' );const ponto =await api.get ('/ponto/historico?mes=2026-04' );
session = requests.Session () session.headers.update({'Authorization' :f'Bearer {token}' ,'Content-Type' :'application/json' })# Use a session para todas as chamadas: funcionarios = session.get ('https://pontofacil.net.br/api/usuarios' ).json() ponto = session.get ('https://pontofacil.net.br/api/ponto/historico?mes=2026-04' ).json()
Passo 3 — Buscar lista de funcionários
Retorna todos os colaboradores da sua empresa. Use o campo id de cada funcionário para consultas específicas nos próximos passos.
const { data } =await api.get ('/usuarios' , { params: { page:1 , limit:100 } });// data.data → array de funcionários // data.total → total de registros data.data.forEach (f => { console.log (`${f.matricula} | ${f.nome} | ${f.cargo} | ativo: ${f.ativo}` ); });// Exemplo de saída: // 00042 | Maria Souza | Analista | ativo: true // 00043 | Carlos Lima | Desenvolvedor | ativo: true
curl https://pontofacil.net.br/api/usuarios?limit=5 \ -H"Authorization: Bearer SEU_TOKEN"
Passo 4 — Consultar registros de ponto
Use o usuario_id obtido no passo anterior para buscar as batidas de qualquer período. Gestores e administradores podem consultar qualquer funcionário.
async function buscarPontoMes (usuarioId, mes) {const { data } =await api.get ('/ponto/historico' , { params: { usuario_id: usuarioId, mes }// mes = "2026-04" });return data.data.map (r => ({ data: r.data_hora.substring (0 ,10 ), hora: r.data_hora.substring (11 ,16 ), tipo: r.tipo,// entrada | saida_almoco | retorno_almoco | saida metodo: r.metodo,// facial | pin | manual status: r.status,// aprovado | pendente_aprovacao | rejeitado })); }const batidas =await buscarPontoMes ('uuid-do-funcionario' ,'2026-04' );// [{ data: "2026-04-18", hora: "08:02", tipo: "entrada", ... }, ...]
# Retorna todos que bateram entrada hoje e ainda não saíram presentes = session.get ('https://pontofacil.net.br/api/dashboard/presenca-agora' ).json()for pin presentes['data' ]:f"{p['nome']:30} → último ponto: {p['ultimo_tipo']} às {p['ultima_batida']}" )# João da Silva → último ponto: retorno_almoco às 13:22
Passo 5 — Consultar apuração e folha
Obtenha o resumo de horas do mês (banco de horas, faltas, atrasos) e os valores da folha de pagamento calculada.
async function apuracaoMes (usuarioId, mes) {const { data } =await api.get ('/apuracao/mes' , { params: { usuario_id: usuarioId, mes } });const r = data.data; console.log (`Horas trabalhadas: ${r.horas_trabalhadas}` ); console.log (`Horas extras: ${r.horas_extras}` ); console.log (`Faltas: ${r.faltas}` ); console.log (`Saldo acumulado: ${r.saldo_minutos} min` ); }
async function folhaMes (usuarioId, mes) {const { data } =await api.get ('/folha' , { params: { usuario_id: usuarioId, mes } });const f = data.data; console.log (`Salário base: R$ ${f.salario_base.toFixed(2)}` ); console.log (`Horas extras: + R$ ${f.horas_extras_valor.toFixed(2)}` ); console.log (`INSS: - R$ ${f.inss.toFixed(2)}` ); console.log (`IRRF: - R$ ${f.irrf.toFixed(2)}` ); console.log (`Líquido: R$ ${f.liquido.toFixed(2)}` ); console.log (`Status: ${f.status}` );// calculada | fechada }
Passo 6 — Renovar o token automaticamente
O token expira em 15 minutos. Em vez de fazer login toda hora, implemente a renovação automática com o refresh_token.
let currentToken ='' ;let currentRefreshToken ='' ;// Intercepta todo erro 401 e tenta renovar automaticamente api.interceptors.response.use ( res => res,async err => {if (err.response?.status ===401 ) {const { data } =await axios.post ('https://pontofacil.net.br/api/auth/refresh' , { refresh_token: currentRefreshToken }); currentToken = data.data.token; api.defaults.headers['Authorization' ] =`Bearer ${currentToken}` ;// Repete a requisição original com o novo token err.config.headers['Authorization' ] =`Bearer ${currentToken}` ;return axios(err.config); }return Promise.reject (err); } );
Passo 7 — Configurar webhook para receber eventos em tempo real
Em vez de ficar consultando a API periodicamente, configure um webhook: o PontoFácil notifica sua URL instantaneamente a cada evento. Requer perfil admin.
7a — Crie o endpoint receptor no seu sistema:
const express =require ('express' );const crypto =require ('crypto' );const app = express();const WEBHOOK_SECRET ='cole_aqui_o_secret_recebido_ao_criar' ; app.use (express.json ()); app.post ('/webhooks/pontofacil' , (req, res) => {// 1. Valida a assinatura ANTES de processar const assinaturaRecebida = req.headers['x-pontofacil-sign' ];const assinaturaEsperada ='sha256=' + crypto .createHmac ('sha256' , WEBHOOK_SECRET) .update (JSON.stringify (req.body)) .digest ('hex' );if (assinaturaRecebida !== assinaturaEsperada) {return res.status (401 ).json ({ error:'Assinatura inválida' }); }// 2. Responde imediatamente (antes de processar!) res.status (200 ).json ({ recebido:true });// 3. Processa em background const { evento, data, empresa_id } = req.body; setImmediate(() =>processarEvento (evento, data, empresa_id)); });async function processarEvento (evento, data, empresaId) {switch (evento) {case 'ponto.registrado' :// Sincronize com seu ERP, envie notificação, etc. console.log (`${data.nome} bateu ${data.tipo} às ${data.data_hora}` );break ;case 'folha.fechada' :// Inicie processamento de folha no seu sistema console.log (`Folha ${data.mes} fechada para ${data.total_funcionarios} funcionários` );break ;case 'funcionario.criado' :// Sincronize o novo colaborador com seu cadastro console.log (`Novo funcionário: ${data.nome} (${data.cargo})` );break ; } } app.listen (3000 );
from flaskimport Flask, request, jsonifyimport hmac, hashlib app = Flask(__name__) SECRET =b'cole_aqui_o_secret_recebido_ao_criar' @app.route('/webhooks/pontofacil' , methods=['POST' ])def receber_webhook ():# 1. Valida assinatura recebida = request.headers.get('X-PontoFacil-Sign' ,'' ) esperada ='sha256=' + hmac.new (SECRET, request.data, hashlib.sha256).hexdigest ()if not hmac.compare_digest (recebida, esperada):return jsonify (error='Assinatura inválida' ),401 # 2. Responde imediatamente payload = request.get_json ()processar_evento (payload)# chame em thread separada em prod return jsonify (recebido=True ),200 def processar_evento (payload): evento = payload['evento' ] data = payload['data' ]if evento =='ponto.registrado' :f"{data['nome']} bateu {data['tipo']} às {data['data_hora']}" )elif evento =='folha.fechada' :f"Folha {data['mes']} fechada" )
7b — Registre sua URL no PontoFácil via API:
const { data } =await api.post ('/webhooks' , { nome:'ERP Principal' , url:'https://seu-sistema.com.br/webhooks/pontofacil' , eventos: ['ponto.registrado' ,'folha.fechada' ,'funcionario.criado' ]// Ou eventos: ['*'] para receber TODOS os eventos }); console.log (`Webhook criado: ${data.data.id}` ); console.log (`Secret: ${data.data.secret}` );// ⚠️ guarde agora — não aparece mais!
curl -X POST https://pontofacil.net.br/api/webhooks \ -H"Authorization: Bearer SEU_TOKEN" \ -H"Content-Type: application/json" \ -d'{"nome":"ERP","url":"https://seu-erp.com/hook","eventos":["*"]}'
7c — Teste o webhook antes de ir para produção:
const webhookId ='uuid-retornado-na-criacao' ;// Dispara um ponto.registrado de teste para sua URL await api.post (`/webhooks/${webhookId}/testar` );// Verifique os logs para ver se chegou: const { data } =await api.get (`/webhooks/${webhookId}/logs` ); data.data.forEach (log => { console.log (`${log.evento} → HTTP ${log.status_code} | sucesso: ${log.sucesso} | tentativas: ${log.tentativas}` ); });
Passo 8 — Tratar erros corretamente
A API sempre retorna um campo error com código legível por máquina. Trate os mais comuns:
async function chamadaSegura (fn) {try {return await fn(); }catch (err) {const codigo = err.response?.data?.error;const msg = err.response?.data?.message;const status = err.response?.status;switch (codigo) {case 'NAO_AUTENTICADO' :// Token expirou — renove e tente novamente await renovarToken ();break ;case 'SEM_PERMISSAO' : console.error('Usuário sem permissão para este recurso' );break ;case 'MODULO_NAO_CONTRATADO' : console.error('Módulo não incluso no plano. Faça upgrade.' );break ;case 'RATE_LIMIT' :// Aguarde e tente novamente await new Promise(r => setTimeout(r,60000 ));break ;default : console.error(`Erro ${status}: ${msg}` ); } } }
Checklist de integração
✅ Login funcionando e token sendo renovado automaticamente
✅ Todas as chamadas enviando o header
Authorization: Bearer ...✅ Endpoint de webhook respondendo HTTP 200 em menos de 10 segundos
✅ Assinatura HMAC sendo validada antes de processar o payload
✅ Evento de teste disparado e recebido com sucesso (verifique logs)
✅ Tratamento de erro 401 com renovação automática do token
✅ URL do webhook em HTTPS (HTTP é rejeitado)
Webhooks
Receba notificações em tempo real sempre que eventos ocorrerem no PontoFácil. Configure um endpoint HTTPS no seu sistema e o PontoFácil fará um POST automático com os dados do evento.
bate o ponto
processa
disparado
recebe
Eventos disponíveis
Formato do payload recebido
{
"evento" : "ponto.registrado" ,
"timestamp" : "2026-04-18T14:32:07.000Z" ,
"empresa_id" : "uuid-da-sua-empresa" ,
"data" : {
"usuario_id" : "uuid" ,
"nome" : "Carlos Lima" ,
"tipo" : "entrada" ,
"metodo" : "facial" ,
"data_hora" : "2026-04-18T14:32:07.000Z" ,
"latitude" : -23.5505 ,
"longitude" : -46.6333
}
}
Verificando a assinatura (segurança)
Cada requisição inclui o header X-PontoFacil-Sign com uma assinatura HMAC-SHA256 gerada com o secret do seu webhook. Valide sempre antes de processar.
const crypto =require ('crypto' );function validarWebhook (req, secret) {const assinatura = req.headers['x-pontofacil-sign' ];// "sha256=abc123..." const esperada ='sha256=' + crypto .createHmac ('sha256' , secret) .update (JSON.stringify (req.body)) .digest ('hex' );return crypto.timingSafeEqual ( Buffer.from (assinatura), Buffer.from (esperada) ); }
Gerenciar webhooks via API
Requer perfil admin.
Lista todos os webhooks configurados da empresa.
Cria um novo webhook. O campo secret é retornado apenas na criação.
{
"nome" : "ERP Principal" ,
"url" : "https://seu-erp.com.br/webhooks/pontofacil" ,
"eventos" : ["ponto.registrado" , "folha.fechada" ] // ou ["*"] para todos
}
{
"id" : "uuid" ,
"nome" : "ERP Principal" ,
"url" : "https://seu-erp.com.br/webhooks/pontofacil" ,
"eventos" : ["ponto.registrado" , "folha.fechada" ],
"ativo" : true ,
"secret" : "a3f8c2d9e1b4..." , // guarde — não será exibido novamente!
"aviso" : "Guarde o secret — ele não será exibido novamente."
}
Dispara um evento de teste ponto.registrado para a URL configurada. Útil para validar a integração.
Retorna os últimos 100 disparos com status HTTP, erro e timestamp.
Atualiza URL, eventos ou ativa/desativa o webhook.
Remove o webhook permanentemente.