Sumário
1. Visão Geral
Esta API permite que um aplicativo de ponto (APP) se integre ao sistema PontoAgil para:
- Validar empresas e dispositivos autorizados.
- Carregar a lista de funcionários liberados para um dispositivo.
- Enviar batidas de ponto com imagem e localização.
- Atualizar batidas (ajustes manuais/aprovações), mantendo o log de evidências.
Base URL (ambiente local)
http://127.0.0.1:8000/api
Formato
- Entrada e saída em JSON.
- Codificação UTF-8.
2. Autenticação & Fluxo Geral
2.1 Conceitos principais
| Campo | Origem | Descrição |
|---|---|---|
codigo_empresa |
Manual (cadastrado no PontoAgil) | Código único da empresa para consulta e validação. |
chave (dispositivo) |
Manual (cadastrada no PontoAgil) | Chave de liberação inicial do dispositivo, usada na ativação. |
chave_app |
Gerada pelo APP | Identificador interno do dispositivo (app). Após ativação, é usada em todas as requisições sensíveis (funcionários, batidas). |
2.2 Fluxo resumido do dispositivo
- APP recebe manualmente do usuário:
codigo_empresachave(chave de liberação do dispositivo)
- APP consulta a empresa:
GET /api/empresas/{codigo_empresa}
- APP consulta o dispositivo:
POST /api/dispositivos/consultar
- APP gera uma
chave_app(identificador interno do device) e envia para ativação:POST /api/dispositivos/ativar
- Com o dispositivo ativo, o APP:
- Carrega funcionários:
GET /api/funcionarios - Sincroniza batidas:
POST /api/batidas/sincronizar - Atualiza batidas/apuração:
POST /api/batidas/atualizar
- Carrega funcionários:
3. Endpoints de Empresa
Retorna os dados básicos de uma empresa a partir do seu código.
Parâmetros de caminho
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
codigo |
string | sim | Código da empresa (ex.: RP00155). |
Resposta – 200 OK (exemplo)
{
"id": 1,
"codigo": "RP00155",
"nome": "Empresa Exemplo LTDA",
"cnpj": "12.345.678/0001-90",
"ativo": true
}
Possíveis erros
- 404 – Empresa não encontrada ou inativa.
4. Endpoints de Dispositivos
Consulta um dispositivo cadastrado para uma empresa a partir da chave manual.
Body (JSON)
{
"codigo_empresa": "RP00155",
"chave": "CHAVE-MANUAL-DO-DISPOSITIVO"
}
Campos
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
codigo_empresa |
string | sim | Código da empresa. |
chave |
string | sim | Chave manual do dispositivo cadastrada no sistema de ponto. |
Resposta – 200 OK (exemplo)
{
"dispositivo_id": 5,
"empresa_id": 1,
"filial_id": 2,
"localizacao_id": 3,
"tipo_dispositivo": "APP",
"status": "inativo",
"nome": "Totem Entrada Loja 01"
}
Possíveis erros
- 404 – Empresa não encontrada ou inativa.
- 404 – Dispositivo não encontrado para essa empresa.
Ativa o dispositivo e associa a chave_app gerada pelo APP.
Body (JSON)
{
"codigo_empresa": "RP00155",
"chave": "CHAVE-MANUAL-DO-DISPOSITIVO",
"chave_app": "APP-DEVICE-UUID-OU-TOKEN"
}
Resposta – 200 OK (exemplo)
{
"message": "Dispositivo ativado com sucesso.",
"dispositivo_id": 5,
"empresa_id": 1,
"status": "ativo",
"filial_id": 2,
"localizacao_id": 3
}
Observações
- Se o dispositivo já estiver ativo com
chave_app, a API apenas retorna os dados e a mensagem “Dispositivo já está ativo.”.
5. Endpoints de Funcionários
Retorna a lista de funcionários ativos para a empresa e dispositivo (chave_app) informados.
Parâmetros (query ou body JSON)
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
codigo_empresa |
string | sim | Código da empresa. |
chave_app |
string | sim | Chave do dispositivo gerada pelo APP e gravada na ativação. |
Exemplo de requisição (via query)
GET /api/funcionarios?codigo_empresa=RP00155&chave_app=APP-DEVICE-UUID
Resposta – 200 OK (exemplo)
[
{
"id": 10,
"nome": "João da Silva",
"cpf": "111.222.333-44",
"matricula": "FUNC001",
"cargo": "Vendedor",
"foto_path": "fotos/func_10.jpg",
"senha_colaborador": "1234",
"localizacao_id": 3,
"escala_id": 1,
"ativo": 1
},
{
"id": 11,
"nome": "Maria Souza",
"cpf": "555.666.777-88",
"matricula": "FUNC002",
"cargo": "Caixa",
"foto_path": "fotos/func_11.jpg",
"senha_colaborador": "5678",
"localizacao_id": 3,
"escala_id": 1,
"ativo": 1
}
]
Possíveis erros
- 404 – Empresa não encontrada ou inativa.
- 401 – Dispositivo não autorizado (chave_app inválida ou inativa).
6. Endpoints de Batidas & Apuração
Recebe batidas de ponto do APP, gera/atualiza a apuração do dia e registra logs (imagem/localização).
Body (JSON) – Exemplo
{
"codigo_empresa": "RP00155",
"chave_app": "APP-DEVICE-UUID",
"batidas": [
{
"funcionario_id": 10,
"data": "2025-11-23",
"hora": "08:00:00",
"tipo": "entrada",
"origem": "totem",
"imagem": "fotos/10-20251123-080000.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"funcionario_id": 10,
"data": "2025-11-23",
"hora": "12:00:00",
"tipo": "saida_intervalo",
"origem": "totem",
"imagem": "fotos/10-20251123-120000.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"funcionario_id": 10,
"data": "2025-11-23",
"hora": "13:00:00",
"tipo": "retorno_intervalo",
"origem": "totem",
"imagem": "fotos/10-20251123-130000.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"funcionario_id": 10,
"data": "2025-11-23",
"hora": "17:00:00",
"tipo": "saida",
"origem": "totem",
"imagem": "fotos/10-20251123-170000.jpg",
"localizacao": "-8.41423,-37.05411"
}
]
}
Regras
- No mesmo payload, para cada
funcionario_id + data:- mínimo 1 batida
- máximo 4 batidas
- Somando com as batidas já salvas para aquela data:
- O total não pode ultrapassar 4; se passar, o grupo é recusado.
- Cada batida pode trazer:
imagem(string) – caminho ou URL da fotolocalizacao(string) – coordenadas ou texto
Resposta – 200 OK (exemplo)
{
"sucesso": true,
"quantidade_processada": 4,
"apuracoes": [
{
"apuracao_id": 123,
"empresa_id": 1,
"funcionario_id": 10,
"data": "2025-11-23",
"batidas": [
"08:00:00",
"12:00:00",
"13:00:00",
"17:00:00"
],
"minutos_trabalhados": 480,
"batida_impar": false,
"batida_inregular": false,
"status_apuracao": "apurado",
"logs": [
{
"hora": "08:00:00",
"imagem": "fotos/10-20251123-080000.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"hora": "12:00:00",
"imagem": "fotos/10-20251123-120000.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"hora": "13:00:00",
"imagem": "fotos/10-20251123-130000.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"hora": "17:00:00",
"imagem": "fotos/10-20251123-170000.jpg",
"localizacao": "-8.41423,-37.05411"
}
]
}
],
"erros": []
}
Observação: o campo minutos_trabalhados é calculado em pares de batidas:
(1ª–2ª), (3ª–4ª), somando a diferença em minutos entre cada par.
Atualiza a apuração de um dia específico (batidas e logs) para um funcionário.
Body (JSON) – Exemplo
{
"codigo_empresa": "RP00155",
"chave_app": "APP-DEVICE-UUID",
"apuracao_id": 123,
"funcionario_id": 10,
"batidas": [
{
"hora": "08:05:00",
"data": "2025-11-23",
"imagem": "fotos/10-20251123-080500.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"hora": "12:02:00",
"data": "2025-11-23",
"imagem": "fotos/10-20251123-120200.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"hora": "13:10:00",
"data": "2025-11-23",
"imagem": "fotos/10-20251123-131000.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"hora": "17:01:00",
"data": "2025-11-23",
"imagem": "fotos/10-20251123-170100.jpg",
"localizacao": "-8.41423,-37.05411"
}
]
}
Regras
batidasdeve conter entre 1 e 4 itens.- Cada item precisa de
hora(obrigatório) e pode opcionalmente trazerdata,imagemelocalizacao. - Se
datafor enviada, deve bater com a data da apuração ou a requisição é recusada. - A apuração é totalmente substituída pelas novas batidas, e os logs são recriados.
Resposta – 200 OK (exemplo)
{
"sucesso": true,
"apuracao": {
"apuracao_id": 123,
"empresa_id": 1,
"funcionario_id": 10,
"data": "2025-11-23",
"batidas": [
"08:05:00",
"12:02:00",
"13:10:00",
"17:01:00"
],
"minutos_trabalhados": 468,
"batida_impar": false,
"batida_inregular": false,
"status_apuracao": "apurado",
"logs": [
{
"hora": "08:05:00",
"imagem": "fotos/10-20251123-080500.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"hora": "12:02:00",
"imagem": "fotos/10-20251123-120200.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"hora": "13:10:00",
"imagem": "fotos/10-20251123-131000.jpg",
"localizacao": "-8.41423,-37.05411"
},
{
"hora": "17:01:00",
"imagem": "fotos/10-20251123-170100.jpg",
"localizacao": "-8.41423,-37.05411"
}
]
}
}
Possíveis erros
- 404 – Empresa não encontrada ou inativa.
- 401 – Dispositivo não autorizado.
- 404 – Apuração não encontrada.
- 403 – Apuração não pertence à empresa ou ao funcionário informado.
- 422 – Data das batidas não corresponde à data da apuração.
7. Estruturas de Dados (Modelos)
7.1 Apuração de batidas (apuracoes_batidas)
| Campo | Tipo | Descrição |
|---|---|---|
id | bigint | Identificador da apuração. |
empresa_id | bigint | Empresa da apuração. |
funcionario_id | bigint | Funcionário da apuração. |
data | date | Dia de referência da apuração. |
escala_nome | string (nullable) | Texto com o nome da escala (futuro relacionamento). |
batidas | json | Array de horários (ex.: ["08:00:00","12:00:00"]). |
motivo | string (nullable) | Motivo textual (justificativa). |
status_apuracao | string | nao_apurado, apurado ou pendente. |
minutos_trabalhados | int | Total de minutos calculados a partir dos pares de batidas. |
observacao | string (nullable) | Observações gerais do dia. |
inclui_espelho | bool | Indica se está incluída no espelho. |
batida_impar | bool | true se quantidade de batidas for ímpar. |
batida_inregular | bool | Usado para marcar batidas fora da escala (futuro). |
7.2 Log de apuração (log_apuracoes)
| Campo | Tipo | Descrição |
|---|---|---|
id | bigint | Identificador do log. |
apuracao_id | bigint | Referência à apuração (apuracoes_batidas.id). |
empresa_id | bigint | Empresa. |
funcionario_id | bigint | Funcionário. |
data | date | Data da batida. |
hora | time | Hora da batida. |
imagem_path | string | Caminho/URL da imagem capturada. |
localizacao | string | Localização textual ou coordenadas. |