Good Integration Practices Use page_size Suitable HTTP # Para bulk sync — máximo por página
GET /empregados/?page_size=100
# Para UI — menor latência
GET /empregados/?page_size=20
Filter in API, not code Python # ❌ Ineficiente: traz tudo e filtra localmente
todos = listar_todos ( "/empregados/" , headers )
ativos = [ e for e in todos if e [ "is_active" ]]
# ✅ Eficiente: filtra na API
ativos = listar_todos ( "/empregados/?is_active=true" , headers )
Unchangeable Response Cache Python from functools import lru_cache
import time
class CachedPontotelClient :
def __init__ ( self , auth , cache_ttl_seconds = 300 ):
self . auth = auth
self . cache = {}
self . cache_ttl = cache_ttl_seconds
def get ( self , url : str ) -> dict :
now = time . time ()
if url in self . cache :
cached_data , cached_at = self . cache [ url ]
if now - cached_at < self . cache_ttl :
return cached_data
headers = self . auth . get_headers ()
response = requests . get ( url , headers = headers )
response . raise_for_status ()
data = response . json ()
self . cache [ url ] = ( data , now )
return data
Security Credential Storage Python # ✅ Correto: Usar variáveis de ambiente
import os
from dotenv import load_dotenv
load_dotenv ()
USERNAME = os . getenv ( "PONTOTEL_USERNAME" )
PASSWORD = os . getenv ( "PONTOTEL_PASSWORD" )
# ❌ Nunca hardcode credenciais
USERNAME = "meu_usuario" # NÃO FAÇA ISSO
Never commit credentials
Add .env ed .gitignore Use secret managers (AWS Secrets Manager, HashiCorp Vault, etc.) Rotate credentials regularly Use separate credentials for Sandbox and Production Required HTTPS Python # ✅ Sempre HTTPS
base_url = "https://apis.pontotel.com.br"
# ❌ Nunca HTTP
base_url = "http://apis.pontotel.com.br"
Impotence Idempotent operations can certainly be repeated without duplicate effects.
Search before creating Python def criar_ou_atualizar_empregado ( dados : dict , headers : dict ) -> dict :
"""Garante idempotência verificando antes de criar"""
# 1. Verificar se já existe
existente = buscar_empregado ( dados [ "cpf" ], dados [ "empregador_id" ], headers )
if existente :
# 2. Atualizar se necessário
if dados_diferentes ( existente , dados ):
return atualizar_empregado ( existente [ "id" ], dados , headers )
return existente
# 3. Criar apenas se não existir
return criar_empregado ( dados , headers )
Language Code Examples Python
Python import requests
import os
from datetime import datetime , timedelta
class PontotelClient :
BASE_URL = "https://apis.pontotel.com.br/pontotel/api/v4"
def __init__ ( self ):
self . session = requests . Session ()
self . token = None
self . token_expires_at = None
def _ensure_authenticated ( self ):
if not self . token or datetime . now () >= self . token_expires_at :
self . _login ()
def _login ( self ):
r = self . session . post ( f " { self . BASE_URL } /login/" , json = {
"username" : os . getenv ( "PONTOTEL_USERNAME" ),
"password" : os . getenv ( "PONTOTEL_PASSWORD" )
})
r . raise_for_status ()
data = r . json ()
self . token = data [ "access_token" ]
self . token_expires_at = datetime . now () + timedelta ( seconds = data [ "expires_in" ] - 60 )
def get ( self , path : str , params : dict = None ) -> dict :
self . _ensure_authenticated ()
r = self . session . get (
f " { self . BASE_URL }{ path } " ,
headers = { "Authorization" : f "Bearer { self . token } " },
params = params
)
r . raise_for_status ()
return r . json ()
def post ( self , path : str , payload : dict ) -> dict :
self . _ensure_authenticated ()
r = self . session . post (
f " { self . BASE_URL }{ path } " ,
headers = { "Authorization" : f "Bearer { self . token } " },
json = payload
)
r . raise_for_status ()
return r . json ()
==="JavaScript"
JavaScript class PontotelClient {
constructor () {
this . baseUrl = 'https://apis.pontotel.com.br/pontotel/api/v4' ;
this . token = null ;
this . tokenExpiresAt = null ;
}
async ensureAuthenticated () {
if ( ! this . token || Date . now () >= this . tokenExpiresAt ) {
await this . login ();
}
}
async login () {
const response = await fetch ( ` ${ this . baseUrl } /login/` , {
method : 'POST' ,
headers : { 'Content-Type' : 'application/json' },
body : JSON . stringify ({
username : process . env . PONTOTEL_USERNAME ,
password : process . env . PONTOTEL_PASSWORD
})
});
const data = await response . json ();
this . token = data . access_token ;
this . tokenExpiresAt = Date . now () + ( data . expires_in - 60 ) * 1000 ;
}
async get ( path , params = {}) {
await this . ensureAuthenticated ();
const url = new URL ( ` ${ this . baseUrl }${ path } ` );
Object . entries ( params ). forEach (([ k , v ]) => url . searchParams . append ( k , v ));
const response = await fetch ( url , {
headers : { 'Authorization' : `Bearer ${ this . token } ` }
});
if ( ! response . ok ) throw new Error ( `API Error: ${ response . status } ` );
return response . json ();
}
}
Next Steps