Spese

Spese, pagamenti e categorie.

11 endpoint Versione v1 · revisione 2026-10-31

Gli endpoint sono relativi a https://api.officina.it e richiedono l'header Authorization: Bearer con la chiave API e X-API-Version: 2026-10-31. L'header della revisione è obbligatorio: differenza fra v1 e revisione; le novità di ogni revisione sono nell'elenco delle revisioni.

GET /v1/expense-categories
Permesso richiesto expenses.read

Elenca le categorie di spesa

Le categorie configurate dall'officina, da usare per valorizzare expense_category_id.
Risposte
200
Le categorie di spesa.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
La chiave non ha il permesso richiesto per questa operazione.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl https://api.officina.it/v1/expense-categories \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "data": [
    {
      "object": "expense_category",
      "id": "1a6f8d47-3c92-4e05-b731-8d2b5a9c4e60",
      "name": "Ricambi"
    },
    {
      "object": "expense_category",
      "id": "5d2c9b78-4e13-40fa-8265-3b7a1f6d9c04",
      "name": "Utenze"
    }
  ],
  "has_more": false,
  "url": "/v1/expense-categories"
}
GET /v1/expenses
Permesso richiesto expenses.read

Elenca le spese

Le spese registrate. Filtra per stato con status, per fornitore con supplier_id e per periodo con from / to.
Risposte
200
Le spese registrate.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
La chiave non ha il permesso richiesto per questa operazione.
422
Un campo della richiesta manca o non è valido: «param» indica quale.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl https://api.officina.it/v1/expenses \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "data": [
    {
      "object": "expense",
      "id": "ba38f519-4c72-4e06-9d81-5a2c7f4b3e90",
      "seq_number": 91,
      "supplier_id": "6f2b8c14-9d70-4a35-b8e2-1c5f7a3d9e60",
      "supplier_name": "Ricambi Lombardia S.r.l.",
      "expense_category_id": "1a6f8d47-3c92-4e05-b731-8d2b5a9c4e60",
      "category_name": "Ricambi",
      "description": "Ricambi vari luglio",
      "invoice_number": "2026/1184",
      "comments": null,
      "status": "to_pay",
      "expired": false,
      "payment_method": "MP05",
      "payment_due_at": "2026-08-31T00:00:00Z",
      "total_before_tax": 420.0,
      "total_tax": 92.4,
      "total_after_tax": 512.4,
      "total_discount": 0,
      "total_payments": 0,
      "outstanding_payments": 512.4,
      "is_stornata": false,
      "created_at": "2026-07-28T09:15:00Z",
      "updated_at": "2026-07-28T09:15:00Z"
    }
  ],
  "has_more": false,
  "url": "/v1/expenses",
  "date_filter": {
    "object": "date_filter",
    "preset": "year",
    "from": "2026-01-01",
    "to": "2026-12-31"
  }
}
POST /v1/expenses
Permesso richiesto expenses.write

Registra una spesa

Registra una spesa verso un fornitore. Gli importi si passano al netto (total_before_tax) e come imposta (total_tax): il totale lordo è calcolato dal server.
Risposte
201
La spesa registrata.
400
Corpo della richiesta non leggibile o JSON non valido.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
La chiave non ha il permesso richiesto per questa operazione.
422
Un campo della richiesta manca o non è valido: «param» indica quale.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl -X POST https://api.officina.it/v1/expenses \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31" \
  -H "Content-Type: application/json" \
  -d '{
  "supplier_id": "6f2b8c14-9d70-4a35-b8e2-1c5f7a3d9e60",
  "description": "Ricambi vari luglio",
  "invoice_number": "2026/1184",
  "payment_method": "MP05",
  "payment_due_at": "2026-08-31T00:00:00Z",
  "total_before_tax": 420.0,
  "total_tax": 92.4
}'
Risposta
{
  "object": "expense",
  "id": "ba38f519-4c72-4e06-9d81-5a2c7f4b3e90",
  "seq_number": 91,
  "supplier_id": "6f2b8c14-9d70-4a35-b8e2-1c5f7a3d9e60",
  "supplier_name": "Ricambi Lombardia S.r.l.",
  "expense_category_id": "1a6f8d47-3c92-4e05-b731-8d2b5a9c4e60",
  "category_name": "Ricambi",
  "description": "Ricambi vari luglio",
  "invoice_number": "2026/1184",
  "comments": null,
  "status": "to_pay",
  "expired": false,
  "payment_method": "MP05",
  "payment_due_at": "2026-08-31T00:00:00Z",
  "total_before_tax": 420.0,
  "total_tax": 92.4,
  "total_after_tax": 512.4,
  "total_discount": 0,
  "total_payments": 0,
  "outstanding_payments": 512.4,
  "is_stornata": false,
  "created_at": "2026-07-28T09:15:00Z",
  "updated_at": "2026-07-28T09:15:00Z"
}
GET /v1/expenses/by-number/{year}/{number}
Permesso richiesto expenses.read

Recupera la spesa dal numero

Restituisce la spesa con il numero number dell'anno year (anno della data della spesa): lo stesso numero mostrato nell'app, per esempio 12/2026. Risponde come il recupero per id. Se il numero corrisponde a più documenti — numeri ripetuti nello storico — restituisce 409 ambiguous_number con gli id in candidates.
dalla revisione 2026-10-04

Nuovo: recupera la spesa dal numero e dall'anno.

Risposte
200
La spesa, con la stessa risposta del recupero per id.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
La chiave non ha il permesso richiesto per questa operazione.
404
La risorsa non esiste, è stata eliminata o non appartiene alla tua officina.
409
Il numero corrisponde a più documenti: scegli quello giusto tra i `candidates` e recuperalo per id.
422
Un campo della richiesta manca o non è valido: «param» indica quale.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl https://api.officina.it/v1/expenses/by-number/{year}/{number} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "expense",
  "id": "ba38f519-4c72-4e06-9d81-5a2c7f4b3e90",
  "seq_number": 91,
  "supplier_id": "6f2b8c14-9d70-4a35-b8e2-1c5f7a3d9e60",
  "supplier_name": "Ricambi Lombardia S.r.l.",
  "expense_category_id": "1a6f8d47-3c92-4e05-b731-8d2b5a9c4e60",
  "category_name": "Ricambi",
  "description": "Ricambi vari luglio",
  "invoice_number": "2026/1184",
  "comments": null,
  "status": "to_pay",
  "expired": false,
  "payment_method": "MP05",
  "payment_due_at": "2026-08-31T00:00:00Z",
  "total_before_tax": 420.0,
  "total_tax": 92.4,
  "total_after_tax": 512.4,
  "total_discount": 0,
  "total_payments": 0,
  "outstanding_payments": 512.4,
  "is_stornata": false,
  "created_at": "2026-07-28T09:15:00Z",
  "updated_at": "2026-07-28T09:15:00Z"
}
GET /v1/expenses/status-counts
Permesso richiesto expenses.read

Conta le spese per stato

Il numero di spese in ciascuno stato, con gli stessi filtri dell'elenco.
Risposte
200
Il numero di spese per stato.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
La chiave non ha il permesso richiesto per questa operazione.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl https://api.officina.it/v1/expenses/status-counts \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "expense_status_counts",
  "to_pay": 6,
  "expired": 2,
  "paid": 143,
  "date_filter": {
    "object": "date_filter",
    "preset": "year",
    "from": "2026-01-01",
    "to": "2026-12-31"
  }
}
GET /v1/expenses/{id}
Permesso richiesto expenses.read

Recupera una spesa

Restituisce la spesa con le righe, le rate, i pagamenti e il residuo da pagare (outstanding_payments).
Risposte
200
La spesa richiesta.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
La chiave non ha il permesso richiesto per questa operazione.
404
La risorsa non esiste, è stata eliminata o non appartiene alla tua officina.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl https://api.officina.it/v1/expenses/{id} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "expense",
  "id": "ba38f519-4c72-4e06-9d81-5a2c7f4b3e90",
  "seq_number": 91,
  "supplier_id": "6f2b8c14-9d70-4a35-b8e2-1c5f7a3d9e60",
  "supplier_name": "Ricambi Lombardia S.r.l.",
  "expense_category_id": "1a6f8d47-3c92-4e05-b731-8d2b5a9c4e60",
  "category_name": "Ricambi",
  "description": "Ricambi vari luglio",
  "invoice_number": "2026/1184",
  "comments": null,
  "status": "to_pay",
  "expired": false,
  "payment_method": "MP05",
  "payment_due_at": "2026-08-31T00:00:00Z",
  "total_before_tax": 420.0,
  "total_tax": 92.4,
  "total_after_tax": 512.4,
  "total_discount": 0,
  "total_payments": 0,
  "outstanding_payments": 512.4,
  "is_stornata": false,
  "created_at": "2026-07-28T09:15:00Z",
  "updated_at": "2026-07-28T09:15:00Z"
}
PATCH /v1/expenses/{id}
Permesso richiesto expenses.write

Aggiorna una spesa

Aggiorna solo i campi presenti nel corpo: gli altri restano invariati.
dalla revisione 2026-10-22

If-Match obbligatorio da questa revisione: senza l'header la richiesta è rifiutata con 428 precondition_required (If-Match: * scrive comunque). Con una version superata risponde 409.

Risposte
200
La spesa aggiornata.
400
Corpo della richiesta non leggibile o JSON non valido.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
La chiave non ha il permesso richiesto per questa operazione.
404
La risorsa non esiste, è stata eliminata o non appartiene alla tua officina.
409
Il documento è stato salvato nel frattempo (la `version` di `If-Match` è superata): ricaricalo e riprova. Nulla è stato salvato.
422
Un campo della richiesta manca o non è valido: «param» indica quale.
428
Manca l'header `If-Match` (obbligatorio dalla revisione 2026-10-22).
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl -X PATCH https://api.officina.it/v1/expenses/{id} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31" \
  -H "Content-Type: application/json" \
  -d '{
  "description": "Ricambi vari luglio (rettificato)",
  "total_before_tax": 400.0,
  "total_tax": 88.0
}'
Risposta
{
  "object": "expense",
  "id": "ba38f519-4c72-4e06-9d81-5a2c7f4b3e90",
  "seq_number": 91,
  "supplier_id": "6f2b8c14-9d70-4a35-b8e2-1c5f7a3d9e60",
  "supplier_name": "Ricambi Lombardia S.r.l.",
  "expense_category_id": "1a6f8d47-3c92-4e05-b731-8d2b5a9c4e60",
  "category_name": "Ricambi",
  "description": "Ricambi vari luglio",
  "invoice_number": "2026/1184",
  "comments": null,
  "status": "to_pay",
  "expired": false,
  "payment_method": "MP05",
  "payment_due_at": "2026-08-31T00:00:00Z",
  "total_before_tax": 420.0,
  "total_tax": 92.4,
  "total_after_tax": 512.4,
  "total_discount": 0,
  "total_payments": 0,
  "outstanding_payments": 512.4,
  "is_stornata": false,
  "created_at": "2026-07-28T09:15:00Z",
  "updated_at": "2026-07-28T09:15:00Z"
}
DELETE /v1/expenses/{id}
Permesso richiesto expenses.write

Elimina una spesa

Eliminazione logica della spesa.
Risposte
200
La spesa eliminata.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
La chiave non ha il permesso richiesto per questa operazione.
404
La risorsa non esiste, è stata eliminata o non appartiene alla tua officina.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl -X DELETE https://api.officina.it/v1/expenses/{id} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "expense",
  "id": "ba38f519-4c72-4e06-9d81-5a2c7f4b3e90",
  "seq_number": 91,
  "supplier_id": "6f2b8c14-9d70-4a35-b8e2-1c5f7a3d9e60",
  "supplier_name": "Ricambi Lombardia S.r.l.",
  "expense_category_id": "1a6f8d47-3c92-4e05-b731-8d2b5a9c4e60",
  "category_name": "Ricambi",
  "description": "Ricambi vari luglio",
  "invoice_number": "2026/1184",
  "comments": null,
  "status": "to_pay",
  "expired": false,
  "payment_method": "MP05",
  "payment_due_at": "2026-08-31T00:00:00Z",
  "total_before_tax": 420.0,
  "total_tax": 92.4,
  "total_after_tax": 512.4,
  "total_discount": 0,
  "total_payments": 0,
  "outstanding_payments": 512.4,
  "is_stornata": false,
  "created_at": "2026-07-28T09:15:00Z",
  "updated_at": "2026-07-28T09:15:00Z"
}
GET /v1/expenses/{id}/payments
Permesso richiesto expenses.read

Elenca i pagamenti della spesa

I pagamenti registrati sulla spesa. Il residuo è outstanding_payments sulla spesa stessa.
Risposte
200
I pagamenti della spesa.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
La chiave non ha il permesso richiesto per questa operazione.
404
La risorsa non esiste, è stata eliminata o non appartiene alla tua officina.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl https://api.officina.it/v1/expenses/{id}/payments \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "data": [
    {
      "object": "expense_payment",
      "id": "d47c0b58-3e91-42a6-8f05-1b9d6a3e2c74",
      "amount": 512.4,
      "payment_method": "MP05",
      "payment_date": "2026-08-01",
      "financial_account_id": "d61c8b04-3f97-4a25-8e70-9b2d5f1a6c38",
      "created_at": "2026-08-01T10:00:00Z"
    }
  ],
  "has_more": false,
  "url": "/v1/expenses/ba38f519-4c72-4e06-9d81-5a2c7f4b3e90/payments"
}
POST /v1/expenses/{id}/payments
Permesso richiesto expenses.write

Registra un pagamento

Registra un pagamento sulla spesa. payment_date è nel formato YYYY-MM-DD e vale la data odierna se omesso. L'importo può essere parziale. A differenza di ogni altro endpoint, la risposta è un 201 **senza corpo**: il pagamento non viene restituito. Rileggi la spesa per vedere i totali aggiornati.
Risposte
201
Pagamento registrato. Risposta senza corpo.
400
Corpo della richiesta non leggibile o JSON non valido.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
La chiave non ha il permesso richiesto per questa operazione.
404
La risorsa non esiste, è stata eliminata o non appartiene alla tua officina.
409
L'operazione è in conflitto con lo stato attuale della risorsa.
422
Un campo della richiesta manca o non è valido: «param» indica quale.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl -X POST https://api.officina.it/v1/expenses/{id}/payments \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31" \
  -H "Content-Type: application/json" \
  -d '{
  "amount": 512.4,
  "payment_method": "MP05",
  "payment_date": "2026-08-01"
}'
DELETE /v1/expenses/{id}/payments/{paymentID}
Permesso richiesto expenses.write

Elimina un pagamento

Rimuove il pagamento e riporta il residuo della spesa al valore precedente.
Risposte
204
Pagamento eliminato. Risposta senza corpo.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
La chiave non ha il permesso richiesto per questa operazione.
404
La risorsa non esiste, è stata eliminata o non appartiene alla tua officina.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl -X DELETE https://api.officina.it/v1/expenses/{id}/payments/{paymentID} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"