API e integrazioni
L'API di Blina Desk
Blina Desk non deve per forza essere il tuo unico programma. Con la REST API gli altri tuoi sistemi leggono e scrivono gli stessi dati che vedi nell'interfaccia, con le stesse regole.
Cosa ci puoi fare
Documenti e ricerca
Elenchi, scarichi e carichi documenti, percorri le cartelle, cerchi nel testo. Quello che carichi fa la stessa strada di qualsiasi altro caricamento: controllo antivirus, OCR, indicizzazione.
Clienti e contatti
Leggi, crei e modifichi aziende e persone, stessi campi obbligatori e stessa cronologia del CRM.
Ordini e fatture
Li crei, aggiungi le righe, cambi lo stato. Il numero del documento lo assegna il server e i totali li calcola il database: nessun client può sovrascriverli.
Leggi le fatture d'acquisto
Le fatture dei fornitori e le loro righe le leggi dall'API. Nascono dalla validazione EN 16931 con riconoscimento dei duplicati, così ogni fattura fa la stessa strada che farebbe dentro il programma.
BASE="https://api.blina-desk.com/api/v1"
curl -s "$BASE/documents?limit=5" -H "Authorization: Bearer $BDK"
curl -s "$BASE/accounts?q=gmbh" -H "Authorization: Bearer $BDK"
curl -s "$BASE/search?q=vertrag" -H "Authorization: Bearer $BDK" Guardalo, invece di leggerlo
Registrato nel programma vero, con dati veri: non è un'animazione.
Come si comincia
- Dal pannello di amministrazione, sotto «API e integrazioni», crei una chiave e le dai i permessi che deve avere. La chiave in chiaro la vedi una volta sola, noi conserviamo solo la sua impronta.
- Mandi la chiave come bearer token. La prima chiamata che risponde ti dice a quale azienda appartiene.
- Leggi, scrivi, e per tutto il resto ti abboni ai webhook invece di interrogare a vuoto.
# testata, il numero lo assegna il server
curl -s -X POST "$BASE/invoices" \
-H "Authorization: Bearer $BDK" -H "Content-Type: application/json" \
-d '{"account_id":"...","issue_date":"2026-07-29"}'
# {"id":"...","invoice_no":"INV-000042","status":"draft","total":0.0}
# righe, i totali li calcola il database
curl -s -X POST "$BASE/invoices/$ID/lines" \
-H "Authorization: Bearer $BDK" -H "Content-Type: application/json" \
-d '{"name":"Beratung","qty":3,"unit_price":100,"vat_rate":19}'
# {"id":"...","total":357.0} <- 3 x 100 + 19% Webhook: lo sai senza chiedere
Invece di andare a vedere se è cambiato qualcosa, te lo facciamo sapere. Ogni consegna è firmata, verifica la firma prima di usare il contenuto.
- L'indirizzo dev'essere https pubblico: indirizzi privati, loopback e link-local vengono rifiutati, alla registrazione e di nuovo a ogni consegna.
- Rispondi 2xx appena hai salvato l'evento. Qualsiasi altra cosa vale come fallimento e viene ritentata: 0s → 30s → 5m → 30m → 2h.
- Dopo cinque consegne esaurite di fila l'indirizzo viene sospeso, e sei tu a riattivarlo.
- Una consegna può arrivare più di una volta: usa l'id dell'evento per capire se l'hai già vista.
Verifica la firma, non è facoltativo
Calcolala sul corpo grezzo, prima di qualsiasi parsing JSON: riserializzare cambia i byte e il confronto fallisce. Rifiuta ciò che non verifica, e ciò che è più vecchio di cinque minuti, anche con il MAC corretto.
import hashlib, hmac, time
def verify(secret: str, raw_body: bytes, header: str, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
ts, sig = int(parts["t"]), parts["v1"]
if abs(time.time() - ts) > tolerance: # anti-replay
return False
expected = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body,
hashlib.sha256).hexdigest()
return hmac.compare_digest(sig, expected) # confronto a tempo costante Quote e sicurezza
- 120 chiamate al minuto e 20.000 al giorno per chiave. Ogni risposta riuscita ti dice a che punto sei; oltre il limite arriva 429 con Retry-After.
- Una chiave porta solo i permessi che le dai, documenti, ricerca, CRM, vendite, acquisti, webhook, concessi uno per uno.
- Ogni risposta porta un X-Request-Id: cita quello e possiamo ricostruire esattamente cos'è successo.
X-RateLimit-Limit-Minute: 120
X-RateLimit-Remaining-Minute: 118
X-RateLimit-Limit-Day: 20000
X-RateLimit-Remaining-Day: 19863