# Onesto.it API > Onesto (onesto.it) è il gestionale fiscale italiano per freelance e piccole imprese: fatture elettroniche con invio allo SdI, spese, tasse e F24, documenti, incassi. Questa è la documentazione per integrarsi via API REST, SDK e webhook. ## In breve - Base URL produzione: `https://api.onesto.it` — Sandbox (dati di prova, token separati): `https://api.sandbox.onesto.it` - Autenticazione: header `Authorization: Bearer `; il token si crea su `https://app.onesto.it/company/integrations` (Impostazioni → Integrazioni). Un token è legato a UNA azienda e a UN ambiente: usato sull'host sbagliato riceve 403 con l'host giusto. - Rate limit: 120 richieste/minuto per token. - Spec OpenAPI 3 completo: `https://docs.onesto.it/openapi.yaml` (testo) o `https://docs.onesto.it/openapi.json` (aggiungi `?ambiente=sandbox` per gli esempi sulla Sandbox). Postman: `https://docs.onesto.it/postman`. - Tutta la documentazione in un solo file: `https://docs.onesto.it/llms-full.txt` (o `https://docs.onesto.it/llms-full.html` come pagina web). ## Quale strada scegliere - Codice che chiama Onesto da un altro sistema (emettere fatture, leggere incassi, creare clienti) → **API REST** (spec OpenAPI) o **SDK Laravel**. - Reagire a qualcosa che succede in Onesto (fattura emessa, incasso, tassa in scadenza) → **webhook** (`POST /v1/hooks`), Zapier o n8n. - L'utente vuole usare Claude in chat sui propri dati, senza codice → non è materia di queste API: si attiva dall'app in Impostazioni → Integrazioni → Claude (MCP). ## Regole che un agente deve conoscere - Gli importi nei payload sono **stringhe decimali** (`"1220.00"`), le date `AAAA-MM-GG`, gli istanti ISO-8601, un dato assente è `null` esplicito. Non convertire gli importi in float per confrontarli. - Una fattura emessa in Italia passa dallo **SdI**: `invia_sdi: true` la trasmette davvero all'Agenzia delle Entrate. È irreversibile: in dubbio crea una bozza (`invia_sdi: false`) e lascia che sia l'utente a emetterla. - `sdi_status` `draft`/`rejected`/`error` = fattura fiscalmente nulla; `delivery_failed` invece è VALIDA (consegnata nel cassetto fiscale). - Note di credito (TD04) e note di debito (TD05) **non si incassano**: `payment_status` è `null` e `POST /fatture/{uuid}/pagamenti` risponde 422. - Per creare una fattura da P.IVA usa `POST /fatture/nuova/piva`: Onesto recupera l'anagrafica dal Registro Imprese. La numerazione (`numerazione`) e il metodo di pagamento (`metodo_pagamento`) si leggono da `GET /fatture/numerazioni` e `GET /fatture/metodi-pagamento`, non si inventano. - Webhook: la sottoscrizione vuole `target_url` (non `url`). Ogni consegna porta `X-Onesto-Signature: sha256=HMAC_SHA256(timestamp + "." + corpo)` col segreto della sottoscrizione e `X-Onesto-Timestamp`: verificala. Rispondi 2xx entro pochi secondi; 410 Gone cancella la sottoscrizione; dopo 20 fallimenti consecutivi viene spenta. `DELETE /v1/hooks/{id}` spegne, non elimina. - I token con ambiti limitati (`abilities`) ricevono 403 sulle rotte fuori ambito; un token di studio/partner vede più aziende e su alcune scritture deve dire quale (`422 ambiguous_account`). - Gli endpoint `/v1/*` sono di sola lettura salvo `hooks`; `/fatture/*` e `/clients/*` sono quelli operativi. ## Documentazione - [Laravel SDK (PHP)](https://docs.onesto.it/#tag/laravel-sdk-php): Pacchetto Composer ufficiale per progetti Laravel. - [Aziende](https://docs.onesto.it/#tag/aziende): Anagrafica delle aziende (account) visibili al token. - [Clienti](https://docs.onesto.it/#tag/clienti) - [Fatture](https://docs.onesto.it/#tag/fatture): Lista delle fatture elettroniche (attive e passive) degli account gestiti, con stato SdI normalizzato e stato di incasso (`payment_status`). - [Spese](https://docs.onesto.it/#tag/spese): Centri di costo delle aziende gestite: la dimensione ANALITICA con cui le spese vengono attribuite a un cliente, un prodotto, una commessa o una sede. - [F24](https://docs.onesto.it/#tag/f24): F24 degli account gestiti: scadenze, importi, stato pagamento, link al PDF e quietanze. - [Scadenze fiscali](https://docs.onesto.it/#tag/scadenze-fiscali): Scadenzario fiscale generico degli account (F24, IVA, INPS, dichiarazioni…). - [Corrispettivi](https://docs.onesto.it/#tag/corrispettivi): Stato del caricamento corrispettivi telematici. - [Automazioni e webhook](https://docs.onesto.it/#tag/automazioni-e-webhook): Endpoint con cui Zapier, n8n e le integrazioni fatte in casa si sottoscrivono agli eventi di Onesto (REST Hooks): catalogo degli eventi disponibili, dati di esempio per configurare i passi a valle, e - [OpenAPI YAML](https://docs.onesto.it/openapi.yaml) / [JSON](https://docs.onesto.it/openapi.json): lo spec macchina, la fonte di tutto. - [SDK e repository](https://github.com/Onesto-it): SDK Laravel, estensione Raycast, app Zapier. ## Endpoint - `GET /v1/accounts` — Lista account - `GET /v1/accounts/{id}` — Dettaglio account - `GET /clients` — Lista clienti - `POST /clients/store/automatic` — Crea cliente da P.IVA - `POST /clients/store/manual` — Crea cliente (manuale) - `GET /fatture/metodi-pagamento` — Lista metodi di pagamento - `GET /fatture/numerazioni` — Lista numerazioni - `POST /fatture/nuova/manuale` — Crea fattura (manuale) - `POST /fatture/nuova/piva` — Crea fattura da P.IVA - `POST /fatture/{uuid}/pagamenti` — Registra incasso - `GET /v1/invoices` — Lista fatture - `GET /v1/cost-centers` — Lista centri di costo - `GET /v1/expenses` — Lista spese classificate - `GET /v1/expenses/summary` — Totali per metodo e per centro - `GET /v1/f24s` — Lista F24 - `GET /v1/f24s/{id}` — Dettaglio F24 (con sezioni tributi) - `GET /v1/tax-deadlines` — Lista scadenze fiscali - `GET /v1/receipts-uploads` — Stato corrispettivi - `GET /v1/events` — Catalogo eventi - `GET /v1/events/{event}/sample` — Esempio di evento - `GET /v1/hooks` — Lista sottoscrizioni - `POST /v1/hooks` — Crea sottoscrizione - `DELETE /v1/hooks/{id}` — Elimina sottoscrizione - `GET /v1/me` — Prova credenziali ## Eventi webhook - `invoice.created` — Fattura emessa: Una nuova fattura è stata creata (bozze escluse). - `invoice.sent` — Fattura inviata: La fattura è stata trasmessa: al Sistema di Interscambio oppure via email al cliente. Il campo "channel" dice quale dei due. - `payment.received` — Incasso ricevuto: È stato registrato un pagamento su una fattura emessa. Scatta anche sugli acconti: "is_fully_paid" dice se la fattura è ora saldata. - `payment.failed` — Pagamento fallito: Il pagamento automatico di un abbonamento di un tuo cliente non è andato a buon fine (addebito rifiutato). - `payment.overdue` — Fattura scaduta non incassata: Una fattura ha superato la data di scadenza e risulta ancora da incassare, in tutto o in parte. Scatta UNA volta sola per fattura. - `quote.accepted` — Preventivo accettato: Il cliente ha accettato e firmato il preventivo online. - `quote.rejected` — Preventivo rifiutato: Il cliente ha rifiutato il preventivo. "reason" contiene il motivo, se lo ha indicato. - `client.created` — Nuovo cliente: È stato aggiunto un cliente in anagrafica. I FORNITORI non fanno scattare questo evento. - `expense.created` — Nuova spesa: È stata registrata una spesa. Gli import massivi (Agenzia delle Entrate) NON fanno scattare questo evento: sono travasi di documenti già esistenti, non fatti nuovi. - `tax.created` — Nuovo bollettino fiscale: È stato generato un bollettino da pagare (F24 o tributo) in scadenza. - `tax.deadline_approaching` — Bollettino in scadenza: Un bollettino non pagato si avvicina alla scadenza (o l'ha superata: "days_until_due" diventa negativo). - `subscription.created` — Nuovo abbonamento: Un tuo cliente ha sottoscritto un abbonamento ricorrente. - `subscription.renewed` — Abbonamento rinnovato: Un abbonamento è entrato in un nuovo periodo di fatturazione. - `subscription.cancelled` — Abbonamento cancellato: Un abbonamento di un tuo cliente è stato cancellato. Esempio di payload per ogni evento: `GET /v1/events/{evento}/sample`. --- # Pagine ## Introduzione Benvenuto nella documentazione ufficiale delle API di **Onesto.it** — il fisco, ma intelligente. Queste API ti permettono di integrare nei tuoi sistemi le funzionalità fiscali di Onesto: creazione fatture attive (manuali o da Partita IVA con recupero dati automatico), invio al **SDI** (Sistema di Interscambio), gestione anagrafica clienti, e altro ancora. URL base: https://api.onesto.it Mentre scorri vedrai a destra (o nel contenuto, da mobile) esempi di codice nei principali linguaggi di programmazione. Puoi cambiare il linguaggio dai tab in alto a destra (o dal menu di navigazione, da mobile). Per andare più veloce mettiamo a disposizione **SDK ufficiali** che gestiscono autenticazione, retry, parsing JSON e modellano i payload con classi tipizzate. Vedi la sezione **SDK** nel menu a sinistra per la lista completa e gli esempi di installazione. Sono open source su [github.com/Onesto-it](https://github.com/Onesto-it). ## Autenticazione Puoi creare e gestire i tuoi token API accedendo a https://app.onesto.it/company/integrations (https://app.onesto.it/company/integrations). Ogni richiesta alle API deve includere un'intestazione: Authorization: Bearer {YOUR_API_TOKEN} I token sono legati alla tua azienda e permettono di accedere alle relative risorse. Produzione e Sandbox hanno host e token separati: un token usato sull'host sbagliato riceve un 403 che indica quello giusto. ## Laravel SDK (PHP) Pacchetto Composer ufficiale per progetti Laravel. - **Repo GitHub**: - **Packagist**: - **Requisiti**: PHP 8.1+, Laravel 9 / 10 / 11 / 12 ## Installazione ```bash composer require onesto-it/laravel-sdk ``` Service provider e alias `Onesto` registrati automaticamente da Laravel package discovery. Nessun setup manuale richiesto. Opzionale — pubblica il file di configurazione: ```bash php artisan vendor:publish --tag=onesto-config ``` ## Configurazione `.env` ```env ONESTO_TOKEN=il_tuo_api_token # opzionale, default https://api.onesto.it ONESTO_URL=https://api.onesto.it # opzionale, default 30s ONESTO_TIMEOUT=30 ``` Il token si genera da **Impostazioni → Integrazioni** ([app.onesto.it/company/integrations](https://app.onesto.it/company/integrations)) nel tuo pannello Onesto. ## Esempi ### Creazione fattura da Partita IVA I dati anagrafici vengono recuperati automaticamente da Onesto: ```php use Onesto; Onesto::createInvoiceFromPIVA([ 'piva' => '01234567890', 'numerazione' => 'Standard', 'issue_date' => '2026-05-20', 'tipo_documento' => 'TD01', 'metodo_pagamento' => 'Bonifico', 'articoli' => [/* ... */], 'scadenze' => [/* ... */], 'invia_sdi' => true, ]); ``` ### Creazione fattura manuale ```php Onesto::createInvoiceManually([ 'cliente' => [ 'ragione_sociale' => 'Acme SRL', 'piva' => '01234567890', 'indirizzo' => 'Via Roma 1', 'cap' => '20121', 'citta' => 'Milano', 'provincia' => 'MI', 'nazione' => 'IT', 'pec' => 'acme@pec.it', ], 'articoli' => [ ['descrizione' => 'Consulenza', 'quantita' => 1, 'prezzo' => 1000, 'iva' => 22], ], 'scadenze' => [ ['data' => '2026-06-30', 'importo' => 1220], ], 'invia_sdi' => true, ]); ``` ### Riferimenti Pubblica Amministrazione (CIG, CUP, ordine, determina…) Per progetti finanziati, appalti pubblici o PNRR puoi passare un oggetto opzionale `pa` con i riferimenti amministrativi. Tutti i campi sono opzionali; quelli passati finiscono nei `` della FatturaPA al momento dell'invio SDI. ```php Onesto::createInvoiceManually([ // ... cliente, articoli, scadenze ... 'pa' => [ 'cig' => 'ZF3392A8B7', 'cups' => ['J53D23000170006', 'K12C24000050001'], 'numero_ordine' => 'ORD-2025-001', 'data_ordine' => '2025-04-15', 'impegno' => 'IMP-123', 'determina' => 'DET-456', 'codice_commessa' => 'COMM-789', ], ]); ``` ### Senza Facade (dependency injection) ```php use OnestoIt\Sdk\Onesto; class FattureController { public function __construct(private Onesto $onesto) {} public function store() { return $this->onesto->createInvoiceManually([/* ... */]); } } ``` L'SDK è un thin wrapper sulle stesse API REST documentate nella sezione **API**: tutto ciò che puoi inviare via HTTP puoi inviarlo via SDK. --- # Riferimento endpoint ## Aziende Anagrafica delle aziende (account) visibili al token. Serve a mappare le aziende Onesto sui clienti del consumer (match su P.IVA / codice fiscale). ### `GET /v1/accounts` — Lista account Ritorna gli account gestiti dal token (tutti i clienti dello studio, o la singola company). Paginato. Parametri: - `page` (query, integer): Numero pagina. - `per_page` (query, integer): Elementi per pagina (max 100). - `updated_since` (query, string): ISO8601: solo account aggiornati da allora. Esempio di risposta: ```json { "data": [ { "id": "12", "name": "TRUE SOLUTIONS S.R.L.", "vat_number": "14288140966", "fiscal_code": "14288140966", "status": "active" } ], "meta": { "page": 1, "per_page": 100, "total": 1, "next_page": null } } ``` ### `GET /v1/accounts/{id}` — Dettaglio account Esempio di risposta: ```json { "data": { "id": "12", "name": "TRUE SOLUTIONS S.R.L.", "vat_number": "14288140966", "fiscal_code": "14288140966", "status": "active" } } ``` ## Clienti ### `GET /clients` — Lista clienti Elenca i clienti dell'azienda in forma paginata, con ricerca opzionale su nome e Partita IVA (`q`). Restituisce l'anagrafica completa (indirizzo, codice SDI, PEC): i dati sono pronti per compilare il blocco `cliente` della creazione fattura senza ulteriori richieste. Parametri: - `q` (query, string): Ricerca su nome o P.IVA. - `page` (query, integer): Pagina (default 1). - `per_page` (query, integer): Elementi per pagina, max 100 (default 50). Esempio di risposta: ```json { "success": true, "data": [ { "id": 1, "name": "ACME Srl", "piva": "01234567890", "codice_fiscale": null, "sdi": "ABCDEFG", "pec": "acme@pec.it", "address": "Via Roma 1", "cap": "20121", "city": "Milano", "province": "MI", "country": "IT", "created_at": "2026-01-15" } ], "meta": { "page": 1, "per_page": 50, "total": 1, "next_page": null } } ``` ### `POST /clients/store/automatic` — Crea cliente da P.IVA Crea un nuovo cliente recuperando automaticamente i dati anagrafici (ragione sociale, indirizzo, comune) dal registro imprese a partire dalla Partita IVA italiana. Basta la sola P.IVA, a tutto il resto pensa Onesto. Parametri: - `piva` (body, string, obbligatorio): Partita IVA valida italiana. Esempio di risposta: ```json { "success": true, "data": { "name": "Azienda SRL", "piva": "01234567890", "city": "Roma" } } ``` ### `POST /clients/store/manual` — Crea cliente (manuale) Crea un nuovo cliente specificando manualmente i dati anagrafici. Utile per clienti esteri o senza Partita IVA italiana. Se la P.IVA indicata è già presente in anagrafica risponde 409 con il cliente esistente. Parametri: - `name` (body, string, obbligatorio): Nome del cliente. - `domain` (body, string): Il campo value non può superare 255 caratteri. - `email` (body, string): Email del cliente. - `phone` (body, string): Telefono. - `address` (body, string): Indirizzo. - `cap` (body, string): CAP. - `city` (body, string): Città. - `province` (body, string): Provincia. - `country` (body, string): default: IT. - `piva` (body, string): Partita IVA. - `sdi` (body, string): Codice SDI. - `pec` (body, string): PEC. Esempio di risposta: ```json { "success": true, "data": { "id": 1, "name": "Mario Rossi", "email": "mario@example.com" } } ``` ## Fatture Lista delle fatture elettroniche (attive e passive) degli account gestiti, con stato SdI normalizzato e stato di incasso (`payment_status`). Usi tipici: intercettare le fatture scartate/in errore e monitorare le fatture non incassate. ### `GET /fatture/metodi-pagamento` — Lista metodi di pagamento Elenca i metodi di pagamento utilizzabili in fattura, con IBAN e codice SDI. I nomi restituiti sono i valori accettati dal campo `metodo_pagamento` degli endpoint di creazione fattura e di registrazione incassi. I conti interni (pocket/sotto-conti) non compaiono: non sono metodi di incasso. Esempio di risposta: ```json { "success": true, "data": [ { "id": 3, "name": "Bonifico bancario", "type": "Bonifico", "iban": "IT60X0542811101000000123456", "sdi_code": "MP05" } ] } ``` ### `GET /fatture/numerazioni` — Lista numerazioni Elenca le numerazioni attive dell'azienda, con l'eventuale metodo di pagamento di default di ciascuna. I nomi restituiti sono i valori accettati dal campo `numerazione` degli endpoint di creazione fattura: usa questo endpoint per popolare i selettori nei client esterni invece di chiedere all'utente di digitare il nome a memoria. Esempio di risposta: ```json { "success": true, "data": [ { "id": 1, "name": "Principale", "type": "standard", "default_payment_method": "Bonifico bancario" } ] } ``` ### `POST /fatture/nuova/manuale` — Crea fattura (manuale) Crea una nuova fattura elettronica specificando tutti i dati via API: cliente, numerazione, articoli, eventuali scadenze di pagamento e invio a SDI (`invia_sdi`, default attivo). I valori di `numerazione` e `metodo_pagamento` sono i NOMI restituiti da `GET /fatture/numerazioni` e `GET /fatture/metodi-pagamento`. Valorizzando `paid` viene registrato subito un incasso pari all'importo indicato. Parametri: - `cliente` (body, object) - `cliente.name` (body, string, obbligatorio): Nome del cliente. - `cliente.piva` (body, string, obbligatorio): Partita IVA del cliente. - `cliente.address` (body, string, obbligatorio): Indirizzo del cliente. - `cliente.cap` (body, string, obbligatorio): CAP del cliente. - `cliente.city` (body, string, obbligatorio): Città del cliente. - `cliente.province` (body, string): Provincia del cliente. - `cliente.country` (body, string): default: IT Paese del cliente. - `cliente.sdi` (body, string): nullable Codice SDI del cliente. - `cliente.pec` (body, string): nullable PEC del cliente. - `cliente.email` (body, string): nullable Email del cliente. - `cliente.phone` (body, string): nullable Telefono del cliente. - `numerazione` (body, string, obbligatorio): Nome della numerazione da usare. - `issue_date` (body, string, obbligatorio): Data di emissione fattura (YYYY-MM-DD). - `tipo_documento` (body, string): in:TD01,TD01_ACC,TD24,TD25 Tipo di documento. - `sconto` (body, number): nullable Sconto globale (importo). - `intestazione` (body, string): nullable Testo da inserire nelle note di intestazione. - `note` (body, string): nullable Note aggiuntive. - `metodo_pagamento` (body, string, obbligatorio): Nome del metodo di pagamento. - `paid` (body, number): nullable Importo già incassato (se presente, viene creato un pagamento). - `articoli` (body, array, obbligatorio): Elenco degli articoli. - `natura` (body, string): nullable Codice natura IVA globale per la fattura. Se omesso, viene determinata automaticamente in base al cliente e regime fiscale. - `scadenze` (body, array): nullable Scadenze di pagamento (se omesso, 30gg da issue_date). - `invia_sdi` (body, boolean): default:true Se inviare la fattura al SDI. - `emails` (body, array): nullable Altre email a cui inviare la fattura. - `pa` (body, object): nullable Riferimenti Pubblica Amministrazione: SOLO CIG e CUP. Obbligatori (se la PA li richiede) per fatture verso Pubblica Amministrazione su progetti finanziati, appalti pubblici, PNRR. Finiscono nei `` della FatturaPA al momento dell'invio SDI. - `pa.cig` (body, string): nullable Codice Identificativo Gara (max 15 chars). - `pa.cup` (body, string): nullable Codice Unico Progetto singolo (max 15 chars). Per fatture con più CUP usa `pa.cups`. - `pa.cups` (body, array): nullable Lista di Codici Unico Progetto (max 15 chars ciascuno). Se passato, prevale su `pa.cup`. - `ordine` (body, object): nullable Riferimenti all'ordine d'acquisto. Validi anche fuori dalla PA (B2B), ma vanno comunque nei `` della FatturaPA insieme a CIG/CUP. Tutti opzionali. - `ordine.numero` (body, string): nullable Numero ordine (max 20 chars). - `ordine.data` (body, string): nullable Data dell'ordine (YYYY-MM-DD). - `ordine.impegno` (body, string): nullable Impegno di spesa (max 100 chars). - `ordine.determina` (body, string): nullable Determina / commessa (max 100 chars). - `ordine.codice_commessa` (body, string): nullable Codice commessa / convenzione (max 100 chars). Esempio di risposta: ```json { "id": 123, "url": "https://fatture.onesto.it/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/pdf" } ``` ### `POST /fatture/nuova/piva` — Crea fattura da P.IVA Crea una nuova fattura elettronica recuperando automaticamente i dati del cliente dalla Partita IVA (lookup sul registro imprese). Numerazione, data e metodo di pagamento sono opzionali: se omessi vengono usati i default dell'azienda. Ideale per emettere una fattura conoscendo solo la P.IVA del cliente e gli articoli. Parametri: - `piva` (body, string, obbligatorio): Partita IVA (con o senza prefisso "IT"). - `numerazione` (body, string): nullable Nome della numerazione da usare. Default: Standard. - `issue_date` (body, string): nullable Data di emissione fattura (YYYY-MM-DD). Default: oggi. - `tipo_documento` (body, string): in:TD01,TD01_ACC,TD24,TD25 nullable Tipo di documento. Default: TD01. - `metodo_pagamento` (body, string): nullable Nome del metodo di pagamento. Default: ultimo usato. - `sconto` (body, number): nullable Sconto globale (importo in Euro). - `intestazione` (body, string): nullable Testo di intestazione. - `note` (body, string): nullable Note aggiuntive. - `invia_sdi` (body, boolean): default:true Se inviare la fattura allo SDI. - `emails` (body, array): nullable Altre email a cui inviare la fattura. - `articoli` (body, array, obbligatorio): Elenco degli articoli. - `articoli[].nome` (body, string, obbligatorio): Nome articolo. - `articoli[].quantita` (body, number, obbligatorio): Quantità. - `articoli[].prezzo` (body, number, obbligatorio): Prezzo unitario. - `articoli[].iva` (body, number, obbligatorio): Aliquota IVA (%). - `articoli[].descrizione` (body, string): nullable Descrizione articolo. - `scadenze` (body, array): nullable Scadenze di pagamento (se omesso, 30gg da issue_date). - `scadenze[].date` (body, string, obbligatorio): Data scadenza (YYYY-MM-DD). - `scadenze[].value` (body, number, obbligatorio): Importo (o percentuale se type = percent). - `scadenze[].type` (body, string): in:percent,amount required Tipo di valore. - `pa` (body, object): nullable Riferimenti Pubblica Amministrazione: SOLO CIG e CUP. Obbligatori (se la PA li richiede) per fatture verso Pubblica Amministrazione su progetti finanziati, appalti pubblici, PNRR. Finiscono nei `` della FatturaPA al momento dell'invio SDI. - `pa.cig` (body, string): nullable Codice Identificativo Gara (max 15 chars). - `pa.cup` (body, string): nullable Codice Unico Progetto singolo (max 15 chars). Per fatture con più CUP usa `pa.cups`. - `pa.cups` (body, array): nullable Lista di Codici Unico Progetto (max 15 chars ciascuno). Se passato, prevale su `pa.cup`. - `ordine` (body, object): nullable Riferimenti all'ordine d'acquisto. Validi anche fuori dalla PA (B2B), ma vanno comunque nei `` della FatturaPA insieme a CIG/CUP. Tutti opzionali. - `ordine.numero` (body, string): nullable Numero ordine (max 20 chars). - `ordine.data` (body, string): nullable Data dell'ordine (YYYY-MM-DD). - `ordine.impegno` (body, string): nullable Impegno di spesa (max 100 chars). - `ordine.determina` (body, string): nullable Determina / commessa (max 100 chars). - `ordine.codice_commessa` (body, string): nullable Codice commessa / convenzione (max 100 chars). Esempio di risposta: ```json { "success": true, "data": { "id": 124, "url": "https://fatture.onesto.it/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/pdf" } } ``` ### `POST /fatture/{uuid}/pagamenti` — Registra incasso Registra un pagamento ricevuto su una fattura esistente, identificata dallo `uuid` (restituito dalla creazione e da `GET /v1/invoices`). L'importo non può superare il residuo da incassare; la risposta include il nuovo stato (`paid`/`partial`/`unpaid`) e il residuo aggiornato. Note di credito (TD04) e documenti fiscalmente nulli (bozze/scartate/errore) non accettano incassi. Parametri: - `amount` (body, number, obbligatorio): Importo incassato (max: residuo). - `payment_date` (body, string): Data incasso (YYYY-MM-DD, default oggi). - `metodo_pagamento` (body, string): Nome del metodo di pagamento (vedi GET /fatture/metodi-pagamento). - `note` (body, string): Nota libera (max 500 caratteri). Esempio di risposta: ```json { "success": true, "payment": { "id": 77, "amount": 500, "payment_date": "2026-07-21" }, "invoice": { "uuid": "9f8b6c1e-0000-0000-0000-000000000000", "number": "2026/145", "total": 1220, "amount_paid": 500, "amount_due": 720, "payment_status": "partial" } } ``` ### `GET /v1/invoices` — Lista fatture Oltre allo stato SdI, ogni fattura espone lo stato di incasso: `payment_status` (`paid`/`partial`/`unpaid`, `null` per note di credito e documenti fiscalmente nulli), `amount_paid`, `amount_due`, `due_date` (ultima scadenza di pagamento) e `overdue`. Per le fatture attive sono inclusi anche `uuid` e `pdf_url`. Parametri: - `account_id` (query, string): Filtra per account. - `direction` (query, string): `outbound` (attive, default) o `inbound` (passive). - `sdi_status` (query, string): Lista separata da virgole (spec): queued,sent,delivered,accepted,rejected,error,failed_delivery. - `payment_status` (query, string): Lista separata da virgole: paid,partial,unpaid,overdue (overdue = non saldata con ultima scadenza passata, solo outbound). Il filtro esclude automaticamente note di credito e di debito (TD04/TD05) e documenti fiscalmente nulli. - `updated_since` (query, string): ISO8601 incrementale. - `page` (query, integer) - `per_page` (query, integer): Max 100. Esempio di risposta: ```json { "data": [ { "id": "123", "account_id": "12", "direction": "outbound", "number": "2026/145", "issue_date": "2026-07-02", "counterpart": { "name": "ACME Srl", "vat_number": "01234567890" }, "total_amount": 1220, "payment_status": "unpaid", "amount_paid": 0, "amount_due": 1220, "due_date": "2026-07-31", "overdue": false, "sdi_status": "delivered", "sdi_error": null, "last_sdi_update": "2026-07-02T10:12:00+02:00", "uuid": "9f8b6c1e-0000-0000-0000-000000000000", "pdf_url": "https://fatture.onesto.it/9f8b6c1e-0000-0000-0000-000000000000/pdf", "url": "https://app.onesto.it/fatture" } ], "meta": { "page": 1, "per_page": 100, "total": 1, "next_page": null } } ``` ## Spese Centri di costo delle aziende gestite: la dimensione ANALITICA con cui le spese vengono attribuite a un cliente, un prodotto, una commessa o una sede. Il riferimento stabile è `code`, non `id`: è quello che i sistemi esterni devono mappare. È univoco per azienda e non cambia quando il centro viene rinominato. ### `GET /v1/cost-centers` — Lista centri di costo Di default include anche i centri disattivati, perché possono avere movimenti storici da interpretare: filtra con `?attivo=1` per i soli centri utilizzabili oggi. Parametri: - `account_id` (query, string): Filtra per azienda. - `attivo` (query, boolean): Solo i centri attivi. - `tipo` (query, string): cliente, prodotto, commessa, sede. - `page` (query, integer) - `per_page` (query, integer): Max 100. Esempio di risposta: ```json { "data": [ { "id": "7", "account_id": "12", "code": "GLOVE", "nome": "Glove ICT", "tipo": "cliente", "client_id": "42", "attivo": true, "created_at": "2026-08-30T10:00:00+02:00" } ], "meta": { "page": 1, "per_page": 100, "total": 1, "next_page": null } } ``` ### `GET /v1/expenses` — Lista spese classificate `allocation_method`: `diretto` (attribuibile a un centro), `personale` (retribuzioni e oneri), `struttura` (spese generali), `escluso` (fuori dall'attività). Una spesa senza metodo vale `struttura`. `cost_center_code` è sempre presente accanto all'id: mappa su quello, non sugli id numerici. Vale `UNASSIGNED` con `needs_review: true` quando la spesa è marcata `diretto` ma il centro non è stato indicato — così quei costi si vedono invece di finire silenziosamente in un altro totale. Parametri: - `account_id` (query, string): Filtra per azienda. - `periodo` (query, string): Mese di competenza YYYY-MM. - `periodo_da` (query, string): Da (YYYY-MM). - `periodo_a` (query, string): A (YYYY-MM). - `method` (query, string): diretto, personale, struttura, escluso. - `cost_center` (query, string): Codice (o id) del centro. - `page` (query, integer) - `per_page` (query, integer): Max 100. Esempio di risposta: ```json { "data": [ { "source": "expense", "id": "2210", "account_id": "12", "document_number": "FT 118", "document_date": "2026-08-20", "periodo_competenza": "2026-09", "allocation_method": "diretto", "cost_center_id": "7", "cost_center_code": "GLOVE", "needs_review": false, "employee_ref": null, "supplier": { "id": "77", "name": "Acme Energia S.p.A." }, "subtotal": "100.00", "vat": "22.00", "total": "122.00", "is_paid": false }, { "source": "payslip", "id": "41", "account_id": "12", "document_number": "Cedolino 2026-09", "document_date": "2026-09-01", "periodo_competenza": "2026-09", "allocation_method": "personale", "cost_center_id": null, "cost_center_code": null, "needs_review": false, "employee_ref": "RSSMRA80A01H501U", "supplier": null, "subtotal": "3480.00", "vat": "0.00", "total": "3480.00", "is_paid": true } ], "meta": { "page": 1, "per_page": 100, "total": 2, "next_page": null } } ``` ### `GET /v1/expenses/summary` — Totali per metodo e per centro I NON ASSEGNATI stanno in un blocco a parte e **non** entrano nei totali: chi consuma vede quanto è in sospeso invece di riceverlo dentro un altro numero. Regola per chi fa il riparto: le non assegnate restano fuori dalla base di costo finché non vengono classificate — meglio un importo in meno che un importo attribuito a caso. Parametri: - `account_id` (query, string): Filtra per azienda. - `periodo` (query, string): Mese di competenza YYYY-MM. - `periodo_da` (query, string): Da (YYYY-MM). - `periodo_a` (query, string): A (YYYY-MM). Esempio di risposta: ```json { "periodo": "2026-09", "totali": { "diretto": "987.00", "personale": "15500.00", "struttura": "1500.00", "escluso": "0.00" }, "per_centro": [ { "cost_center_id": "7", "cost_center_code": "GLOVE", "nome": "Glove ICT", "totale": "987.00", "documenti": 3 } ], "non_assegnate": { "conteggio": 3, "importo": "420.00" } } ``` ## F24 F24 degli account gestiti: scadenze, importi, stato pagamento, link al PDF e quietanze. È il cuore della supervisione fiscale (alert su scaduti / in scadenza). ### `GET /v1/f24s` — Lista F24 Stato (`status`): `ready` = da pagare (pronto per il bonifico), `paid` = pagato, `expired` = scaduto non pagato, `cancelled` = annullato, `draft` = bozza da completare. Parametri: - `account_id` (query, string): Filtra per account. - `status` (query, string): Stato: draft, ready, paid, expired, cancelled. - `due_date_from` (query, string): date Scadenza da (YYYY-MM-DD). - `due_date_to` (query, string): date Scadenza a (YYYY-MM-DD). - `updated_since` (query, string): ISO8601 incrementale. - `page` (query, integer) - `per_page` (query, integer): Max 100. Esempio di risposta: ```json { "data": [ { "id": "9f8a...", "account_id": "12", "taxpayer": { "name": "TRUE SOLUTIONS S.R.L.", "vat_number": "14288140966", "fiscal_code": "14288140966" }, "description": "IVA Trimestrale 2026-Q2", "period": "2026-Q2", "due_date": "2026-08-20", "amount": 12554.23, "total_amount": 12554.23, "currency": "EUR", "status": "ready", "native_status": "PENDING", "payment_date": null, "payment_reference": null, "receipt_available": false, "file_url": "https://onesto-it.s3.eu-south-1.amazonaws.com/f24/...pdf?X-Amz-Signature=...", "url": "https://app.onesto.it/tasse" } ], "meta": { "page": 1, "per_page": 100, "total": 1, "next_page": null } } ``` ### `GET /v1/f24s/{id}` — Dettaglio F24 (con sezioni tributi) ## Scadenze fiscali Scadenzario fiscale generico degli account (F24, IVA, INPS, dichiarazioni…). Estende la supervisione oltre i soli F24. Sorgente: record `taxes`. ### `GET /v1/tax-deadlines` — Lista scadenze fiscali Parametri: - `account_id` (query, string): Filtra per account. - `type` (query, string): f24, lipe, iva, dichiarazione, inps, other. - `status` (query, string): upcoming, due_today, overdue, done. - `due_date_from` (query, string): date YYYY-MM-DD. - `due_date_to` (query, string): date YYYY-MM-DD. - `updated_since` (query, string): ISO8601 incrementale. - `page` (query, integer) - `per_page` (query, integer): Max 100. Esempio di risposta: ```json { "data": [ { "id": "55", "account_id": "12", "type": "iva", "title": "IVA Trimestrale 2026-Q2", "due_date": "2026-08-20", "amount": 12554.23, "status": "upcoming", "related_resource": { "type": "f24", "id": "9f8a..." } } ], "meta": { "page": 1, "per_page": 100, "total": 1, "next_page": null } } ``` ## Corrispettivi Stato del caricamento corrispettivi telematici. ⚠️ Onesto NON gestisce nativamente i corrispettivi/registratori telematici: l'endpoint esiste per completezza del contratto API ma risponde con `supported=false` e lista vuota, così il consumer non lo tratta come errore. Verrà popolato se/quando Onesto introdurrà la gestione dei corrispettivi. ### `GET /v1/receipts-uploads` — Stato corrispettivi Parametri: - `account_id` (query, string): Filtra per account. - `updated_since` (query, string): ISO8601 incrementale. Esempio di risposta: ```json { "data": [], "meta": { "page": 1, "per_page": 100, "total": 0, "next_page": null, "supported": false, "note": "Corrispettivi non gestiti da Onesto" } } ``` ## Automazioni e webhook Endpoint con cui Zapier, n8n e le integrazioni fatte in casa si sottoscrivono agli eventi di Onesto (REST Hooks): catalogo degli eventi disponibili, dati di esempio per configurare i passi a valle, e gestione delle sottoscrizioni. ⚠️ Una sottoscrizione appartiene a UNA azienda: la chiave usata deve essere quella della singola azienda (creata da /company/integrations), non un token di studio che ne vede molte — indovinare l'azienda manderebbe i dati di un cliente dentro l'automazione di un altro. ### `GET /v1/events` — Catalogo eventi Elenco degli eventi a cui ci si può sottoscrivere. Zapier e n8n lo usano per popolare il menu dei trigger: la chiave è il valore da passare in `events`, l'etichetta è quella da mostrare all'utente. Esempio di risposta: ```json { "data": [ { "key": "invoice.created", "label": "Fattura emessa", "description": "Una nuova fattura è stata creata (bozze escluse).", "category": "Fatture" } ] } ``` ### `GET /v1/events/{event}/sample` — Esempio di evento Restituisce un evento di esempio nella STESSA forma di una consegna vera (stesso involucro `event/delivery_id/occurred_at/data`). ⚠️ Serve a Zapier e n8n per far mappare i campi PRIMA che sia mai arrivato un evento vero: senza, l'utente dovrebbe emettere una fattura finta per poter configurare il passo successivo. Esempio di risposta: ```json { "data": { "event": "invoice.created", "delivery_id": "00000000-0000-4000-8000-000000000000", "occurred_at": "2026-08-24T10:00:00+02:00", "data": { "invoice_id": 4821 } } } ``` ### `GET /v1/hooks` — Lista sottoscrizioni Le sottoscrizioni webhook dell'azienda. Il segreto non compare MAI: si vede solo alla creazione. Esempio di risposta: ```json { "data": [ { "id": "7", "name": "Zap: nuova fattura", "target_url": "https://hooks.zapier.com/hooks/standard/123/abc/", "events": [ "invoice.created" ], "source": "zapier", "is_active": true } ] } ``` ### `POST /v1/hooks` — Crea sottoscrizione Registra una destinazione a cui consegnare gli eventi indicati. Se esiste già una sottoscrizione ATTIVA con lo stesso URL e la stessa provenienza, viene aggiornata invece di duplicata: Zapier ripete la subscribe ogni volta che lo Zap viene riacceso, e senza questa regola ogni riaccensione lascerebbe dietro un doppione che consegna due volte. Parametri: - `target_url` (body, string, obbligatorio): Dove consegnare gli eventi. Solo https. - `events` (body, array, obbligatorio): Chiavi degli eventi (vedi GET /v1/events). - `name` (body, string): Etichetta leggibile della sottoscrizione. - `source` (body, string): zapier, n8n o custom (default custom). Esempio di risposta: ```json { "data": { "id": "7", "target_url": "https://hooks.zapier.com/hooks/standard/123/abc/", "events": [ "invoice.created" ], "source": "zapier", "secret": "...", "secret_note": "Conservalo ora: non verrà mostrato di nuovo." } } ``` ### `DELETE /v1/hooks/{id}` — Elimina sottoscrizione Zapier la chiama da solo quando l'utente spegne lo Zap. ### `GET /v1/me` — Prova credenziali Dice a chi possiede la chiave quale azienda vede, cosa può fare e se questa installazione consegna webhook. Zapier e n8n lo chiamano appena l'utente incolla la chiave, per dare subito un errore comprensibile invece di fallire più tardi su un endpoint qualsiasi. Esempio di risposta: ```json { "data": { "token_type": "api_token", "company": { "id": "12", "name": "TRUE SOLUTIONS S.R.L.", "vat_number": "14288140966" }, "accounts_count": 1, "abilities": [ "invoices:read", "webhooks:manage" ], "full_access": false, "webhooks_supported": true, "webhooks_ready": true } } ```