Skip to content

Employee Synchronization

Objective

This guide describes how to synchronize employees (employees) of your HR system with Pontotel.

Prerequisite

Before syncing employees, you must have the Employers already registered. Look: Employers Synchronization →

Synchronization Flow

flowchart LR
    A[Seu Sistema RH] -->|Busca empregados| B[Seu Banco de Dados]
    B -->|Para cada funcionário| C{Existe na Pontotel?}
    C -->|Não| D[POST /empregados/]
    C -->|Sim| E{Dados mudaram?}
    E -->|Sim| F[PATCH /empregados/id/]
    E -->|Não| G[Ignorar]
    D --> H[Armazenar ID Pontotel]

Step 1: Search Employed by CPF or Registration

Python
def buscar_empregado(cpf: str, empregador_id: int, headers: dict) -> dict | None:
    """Busca empregado por CPF dentro de um empregador"""
    response = requests.get(
        "https://apis.pontotel.com.br/pontotel/api/v4/empregados/",
        params={"cpf": cpf, "empregador_id": empregador_id},
        headers=headers
    )
    response.raise_for_status()
    data = response.json()
    return data["results"][0] if data["count"] > 0 else None

Step 2: Create Employee

Python
def criar_empregado(dados: dict, headers: dict) -> dict:
    response = requests.post(
        "https://apis.pontotel.com.br/pontotel/api/v4/empregados/",
        json=dados,
        headers=headers
    )
    response.raise_for_status()
    return response.json()

# Payload completo de criação
payload = {
    "empregador_id": 5,
    "cpf": "123.456.789-00",
    "matricula": "EMP-001",
    "nome": "John Smith",
    "data_admissao": "2025-01-15",
    "email": "joao.silva@empresa.com",
    "is_active": True
}

Step 3: Incremental Sync

In incremental synchronization, we send only the records that have been modified since the last synchronization:

Python
from datetime import datetime, timedelta

def sincronizar_incremental(data_ultima_sync: datetime, auth) -> dict:
    """Sincroniza apenas empregados modificados desde a última sync"""
    headers = auth.get_headers()
    resultado = {"criados": 0, "atualizados": 0, "erros": []}

    # 1. Buscar empregados modificados no seu sistema
    empregados_modificados = seu_sistema.buscar_modificados_desde(data_ultima_sync)

    for func in empregados_modificados:
        try:
            existente = buscar_empregado(func["cpf"], func["empregador_id"], headers)

            if not existente:
                criar_empregado(func, headers)
                resultado["criados"] += 1
            else:
                requests.patch(
                    f"https://apis.pontotel.com.br/pontotel/api/v4/empregados/{existente['id']}/",
                    json=func,
                    headers=headers
                ).raise_for_status()
                resultado["atualizados"] += 1

        except Exception as e:
            resultado["erros"].append({"cpf": func.get("cpf"), "erro": str(e)})

    return resultado

Disconnect Treatment

When an employee is turned off, do not delete the employee — disable it:

Python
def desligar_empregado(id: int, data_demissao: str, headers: dict):
    """Desativa empregado na Pontotel"""
    requests.patch(
        f"https://apis.pontotel.com.br/pontotel/api/v4/empregados/{id}/",
        json={
            "is_active": False,
            "data_demissao": data_demissao
        },
        headers=headers
    ).raise_for_status()

Do not delete employees

Delete an employee erases point and vacation history. Always use is_active: false for deactivation.

Business Rules

Rule Description
Single number per employer Two employees cannot have the same number in the same employer
Optional registration If not informed, the API will automatically generate
Compulsory employee empregador_id is mandatory in creation
Date of admission Must be a valid date in the past or present

Required Fields in Creation

Field Type Description
empregador_id integer Employer ID
cpf string Official number
nome string Full name
data_admissao date Date of admission

Next Steps