Stable Pro

Stable Pro API · v1

Convenzioni

Importi, date, codici, imposte, elenchi e filtri, lingue, versioni.

Richieste e risposte

GET legge. Le risposte sono JSON, coi nomi dei campi in inglese e in snake_case. Ogni risposta porta Cache-Control: no-store. Ogni oggetto ha un campo object che dice cos'è (charge, payment, event…).

Importi

Gli importi sono numeri interi nell'unità minore della loro valuta (ISO 4217), con la valuta accanto: 300,00 € è 30000 con currency: "EUR"; 3.000 ¥ è 3000; 25,500 KWD è 25500.

Ogni importo è il totale che paga il cliente (amount_basis: "gross"): quando Stable Pro calcola l'IVA il totale la comprende, e Stable Pro dà accanto imponibile e imposta. Un programma che applica la sua imposta a un importo di Stable Pro la ricava da quel totale, non la aggiunge.

Gli importi hanno il segno dove conta la direzione: una correzione che abbassa un addebito è negativa, un rimborso è negativo.

Date

  • Le date di calendario (scadenze, periodi, la data di un incasso) sono YYYY-MM-DD; i mesi sono YYYY-MM.
  • Gli istanti (created_at, issued_at, occurred_at…) sono RFC 3339 in UTC: 2026-11-10T14:32:05.120Z.
  • Il mese contabile (accounting_month) lo calcola Stable Pro nel fuso orario della scuderia: è il più recente fra il mese di competenza e il mese in cui il fatto è stato registrato. Non devi mai fare un calcolo di fuso orario.

Fuso orario, valuta, paese e lingua della scuderia sono in GET /organization.

Codici, non testi

Il contratto espone codici — action, reason, category, origin, i tipi di addebito, i tipi di novità — mai frasi in una lingua. I nomi per le persone vengono dal dizionario, nella lingua richiesta:

curl "https://app.stable-pro.com/api/v1/codes?lang=de" -H "Authorization: Bearer sp_live_…"

GET /codes elenca ogni famiglia di codici, dove compare ogni famiglia (fields, per esempio adjustment.reason) e un name per ogni codice. Il nome di un reason dipende dalla sua action: cercalo con tutti e due.

Gli elenchi di codici sono aperti: un valore nuovo può arrivare dentro la v1. La tua integrazione deve accettare un codice che ancora non conosce (e può leggerne il nome da /codes). taxonomy_version dice quale versione della tassonomia delle correzioni ha prodotto una riga.

Dove esiste un elenco standard si usa quello: valuta ISO 4217, paese ISO 3166-1 e suddivisione ISO 3166-2 (IT-MI, US-OH), identificativi fiscali con uno schema ISO 6523, categoria d'imposta UNCL 5305 (S, Z, E, AE, K, G, O), unità UNECE Rec. 20 (MON, ANN, C62).

Imposte

Ogni addebito e ogni correzione dicono:

  • tax_calculated_by: stable_pro (Stable Pro calcola l'IVA e la dà), o external — che vuol dire solo che Stable Pro non la calcola: non vuol dire che l'imposta sia zero;
  • tax_treatment: standard_rated, zero_rated, not_calculated, o undetermined (un fatto più vecchio per cui non si sa);
  • taxable_amount e taxes[]: un elenco, anche con un solo elemento — { type, jurisdiction, category, rate_bp, amount }. Le aliquote sono in punti base: il 22% è 2200.

Un addebito si legge com'è adesso: il suo importo e le sue imposte sono la sua nascita, più le sue correzioni, più ogni cambio d'imposta successivo.

Elenchi

Un elenco contiene tutti i fatti del suo tipo, pagati o no: GET /charges sono tutti gli addebiti ai clienti (mai i compensi dello staff), GET /customers sono tutti quelli che hanno almeno un addebito, soci o staff.

Gli elenchi vanno a cursore:

GET /charges?limit=100&starting_after=<id dell'ultimo elemento che hai letto>
  • limit da 1 a 100 (25 se manca);
  • la busta è { "object": "list", "data": [...], "has_more": true }; chiedi di nuovo con starting_after = l'id dell'ultimo elemento;
  • l'ordine è sempre dal più vecchio: created_at, poi id (ricevute: issued_at, poi id).

Filtri

Alcuni elenchi si restringono con dei filtri, che valgono tutti insieme, con limit e col cursore. Per esempio, gli addebiti di un cliente in un mese:

GET /charges?customer=<id del cliente>&accounting_month=2026-10
ElencoFiltri
GET /chargescustomer, accounting_month
GET /adjustmentscharge, accounting_month
GET /paymentscustomer
GET /credit-entriescustomer
GET /receiptscustomer, payment

customer, charge e payment vogliono un id; accounting_month vuole YYYY-MM ed è il mese contabile, quello in cui il fatto conta (vedi «Date» qui sopra).

Parametri sconosciuti e valori non validi

Un parametro che l'endpoint non conosce non viene mai ignorato: la risposta è 400 invalid-request, e invalid_param dice quale. Così un filtro scritto male (accountingmonth invece di accounting_month) non restituisce mai l'elenco intero. Vale anche per un limit, un cursore o un filtro con un valore non valido. La chiave e i permessi si controllano prima: senza chiave la risposta resta 401, senza permesso 403.

Gli elenchi servono a cercare e a controllare; per restare allineato, leggi le novità (Novità).

Lingue

Il contratto è in inglese e non cambia mai con la lingua. Le frasi per le persone — il detail di un errore, i nomi in /codes — arrivano nella lingua richiesta: ?lang= vince su Accept-Language; senza nessuno dei due, inglese. Disponibili: en, it, fr, de, es. La risposta dice la lingua in Content-Language.

Versioni

La versione è nel percorso: /api/v1/. Dentro la v1 ci sono solo aggiunte: un campo nuovo, un endpoint nuovo, un valore nuovo di un elenco di codici. Tutto ciò che romperebbe un'integrazione è una v2, con almeno un anno di convivenza e le intestazioni Deprecation e Sunset.

Le ricevute non sono documenti fiscali

Le ricevute di Stable Pro confermano un pagamento (fiscal_document: false). Il documento fiscale lo emette il tuo programma. La scuderia può scegliere di non dare le ricevute di Stable Pro ai suoi clienti finché il tuo programma è collegato: GET /organization lo dice in receipts_shown_to_customers. Le ricevute esistono comunque, numerate, e puoi leggerle.