API
Il modulo Webservices è opzionale. Se la versione in uso non lo include, per un preventivo o per approfondimenti contattare l'assistenza.
Il servizio di API espone in lettura e in scrittura determinati dati del gestionale presenze per l'integrazione con sistemi esterni, restituendo risposte in formato JSON.
URL di base
{base_url}/api/<versione>
{base_url} è il dominio della specifica installazione del cliente.
Tutti gli endpoint di questo manuale sono indicati come percorso relativo a questa base.
<versione> è la versione degli endpoint che si desidera utilizzare.
Esempio
{base_url}/api/v1/utenti
Endpoint "extra"
{base_url}/api/extra/<versione>
Alcune risorse non seguono lo schema standard di lista/risorsa di questo manuale: niente paginazione, e i parametri accettati in query string, quando presenti, sono documentati esplicitamente nella pagina della risorsa invece di seguire il sistema di filtri generico. Per il resto si comportano come qualsiasi altro endpoint: stessa autenticazione, stesso formato di risposte ed errori.
L'unica differenza è nell'URL, con il segmento extra in più tra la base e la versione.
Esempio
{base_url}/api/extra/v1/presenti-assenti
Autenticazione
L'autenticazione è per azienda, non per utente: non è richiesto un account personale, ma una password condivisa abilitata a livello di azienda (modulo "web service").
Ogni richiesta deve includere l'header:
Authorization: <azienda>:<password>
dove <azienda> è l'identificativo dell'azienda e <password> è la password del modulo web service.
Se l'azienda non ha questo modulo abilitato, o la password non è corretta, la richiesta viene rifiutata con 401:
{ "error": "Azienda o password errata" }
Limite giornaliero di richieste
Ogni azienda ha un numero massimo di richieste consentite al giorno: il contatore si azzera automaticamente ogni giorno.
Ogni risposta include l'header:
X-Limit-WebService: <richieste_usate_oggi>/<limite_massimo_giornaliero>
Quando il limite viene raggiunto, la richiesta viene rifiutata con 401:
{ "error": "Limite massimo giornaliero raggiunto" }
Paginazione
Gli endpoint che restituiscono liste supportano paginazione tramite query string:
| Parametro | Descrizione | Default |
|---|---|---|
page | Numero di pagina (1-based) | 1 |
limit | Elementi per pagina | 100 (massimo 100, valori superiori vengono troncati a 100) |
Ogni risposta paginata include gli header:
| Header | Descrizione |
|---|---|
X-Total-Count | Numero totale di elementi |
X-Total-Pages | Numero totale di pagine |
X-Limit | Elementi per pagina applicati |
X-Current-Page | Pagina corrente |
Filtri
Le risorse in lettura si filtrano tramite query string, usando i nomi dei campi così come restituiti nella risposta. Un parametro il cui nome non corrisponde a nessun campo esposto genera un errore 400:
{ "error": "Filtro su campo inesistente: 'cognome'" }
Filtro semplice (uguaglianza)
GET /utenti?cognome=Rossi
Filtro con operatore
GET /utenti?assunzione[gte]=2024-01-01
Operatori disponibili:
| Operatore | Significato | Valore atteso |
|---|---|---|
eq | Il campo è uguale al valore indicato (predefinito) | scalare |
neq | Il campo è diverso dal valore indicato | scalare |
lt | Il campo è minore del valore indicato | scalare |
lte | Il campo è minore o uguale al valore indicato | scalare |
gt | Il campo è maggiore del valore indicato | scalare |
gte | Il campo è maggiore o uguale al valore indicato | scalare |
like | Il campo contiene il valore indicato | scalare |
not_like | Il campo non contiene il valore indicato | scalare |
in | Il campo è uguale a uno qualsiasi dei valori indicati in un elenco | array |
not_in | Il campo è diverso da tutti i valori indicati in un elenco | array |
between | Il campo è compreso tra due valori indicati (estremi inclusi) | array di 2 elementi |
not_between | Il campo non è compreso tra due valori indicati | array di 2 elementi |
is_null | Il campo non ha un valore impostato | nessuno |
is_not_null | Il campo ha un valore impostato | nessuno |
Esempi con array (in/between):
GET /giustificazioni?codice_giustificativo[in][]=FER&codice_giustificativo[in][]=MAL
GET /timbrature?data[between][]=2024-01-01&data[between][]=2024-01-31
Un valore vuoto o mancante per un filtro fa sì che quel filtro venga ignorato, tranne per is_null/is_not_null che non richiedono valore.
Filtro su campi annidati
Alcune risorse possono restituire un campo come oggetto annidato invece che come valore semplice, per esempio:
{ "reparto": { "codice": "R01", "descrizione": "Produzione" } }
Per filtrare su un campo di questo tipo, usare __ (doppio underscore) che separa i livelli:
GET /utenti?reparto__codice=R01
Formato delle risposte
GET
Una richiesta GET su una lista restituisce direttamente un array JSON di oggetti:
[
{ "badge": "12345", "cognome": "Rossi", "nome": "Mario" },
{ "badge": "12346", "cognome": "Bianchi", "nome": "Luca" }
]
POST
Le operazioni di scrittura restituiscono un oggetto con un messaggio:
{ "message": "Scadenza creata con successo" }
Errori
Qualsiasi errore si presenta durante la richiesta, restituisce un body JSON: un oggetto con la chiave error e un messaggio testuale.
{ "error": "Descrizione dell'errore" }
Esempi:
| Caso | Codice | Esempio |
|---|---|---|
| Autenticazione fallita | 401 | { "error": "Azienda o password errata" } |
| Filtro su una GET riferito a un campo inesistente | 400 | { "error": "Filtro su campo inesistente: 'xyz'" } |
| Validazione su una POST | 400/404/409/500 | { "error": "Formato data non valido, atteso YYYY-MM-DD" } |
| Rotta inesistente | 404 | { "error": "Risorsa non trovata" } |
| Metodo HTTP non permesso | 405 | { "error": "Metodo non permesso. Metodi ammessi: GET" } |
| Errore interno del server | 500 | { "error": "Errore interno del server" } |
Come effettuare le chiamate
Ogni endpoint documentato in questo manuale riporta in cima alla propria pagina il percorso completo, pronto per essere copiato. Questa pagina spiega il formato comune a tutte le chiamate, a prescindere dalla risorsa.
Tutte le richieste devono includere l'header di autenticazione descritto in Autenticazione.
GET
curl -H "Authorization: miaAzienda:miaPassword" \
"{base_url}/api/v1/utenti?reparto=Produzione"
I parametri di filtro, ordinamento e paginazione si passano in query string — vedi Filtri e Paginazione.
POST
Oltre all'header di autenticazione, le richieste POST richiedono Content-Type: application/json e un body JSON con i campi richiesti dalla risorsa:
curl -X POST \
-H "Authorization: miaAzienda:miaPassword" \
-H "Content-Type: application/json" \
-d '{"data": "2026-09-15", "badge": "12345", "scadenza": "Visita medica", "ciclo": "annuale"}' \
"{base_url}/api/v1/scadenze"
Il body dei campi accettati e il formato della risposta di successo/errore sono documentati nella pagina della singola risorsa.
