Magazzino

Articoli, listino manodopera e movimenti.

7 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/articles
Permesso richiesto articles.read

Cerca nel magazzino e nel listino

Il catalogo dietro «Cerca da magazzino». Contiene sia i ricambi (kind: item) sia le voci di manodopera (kind: work). Ogni parola di q deve comparire nel nome, nel codice o nelle note. Filtra per tipo con kind. Passa customer_id per applicare il listino di quel cliente: sale_price e unit_discount_rate sono quelli da proporre su una nuova riga di scheda o preventivo (prezzo netto del listino con sconto 0, oppure prezzo dell'articolo con lo sconto del listino al posto di quello dell'articolo), e price_list_source dice cosa viene dal listino.
dalla revisione 2026-10-04

Nuovi campi work_category_ids e work_categories su ogni articolo (le categorie per cui si usa) e filtro work_category_id (ripetibile: articoli con almeno uno dei tipi indicati).

Risposte
200
Gli articoli che soddisfano la ricerca.
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/articles \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "data": [
    {
      "object": "article",
      "id": "f18c4b62-9d07-4e53-a294-6b1f8d3c5e70",
      "code": "FO-2231",
      "name": "Filtro olio",
      "kind": "item",
      "unit_type": "pz",
      "stock": 12,
      "sale_price": 14.9,
      "vat_code": "22",
      "unit_discount_rate": 0,
      "work_category_ids": [
        "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40"
      ],
      "work_categories": [
        {
          "object": "work_category",
          "id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
          "name": "Tagliando"
        }
      ]
    },
    {
      "object": "article",
      "id": "2c9e5a71-4b38-40df-9126-7e3d1f6a8c25",
      "code": null,
      "name": "Manodopera meccanica",
      "kind": "work",
      "unit_type": "h",
      "stock": 0,
      "sale_price": 40.0,
      "vat_code": "22",
      "unit_discount_rate": 0,
      "work_category_ids": [],
      "work_categories": []
    }
  ],
  "has_more": false,
  "url": "/v1/articles"
}
POST /v1/articles
Permesso richiesto articles.write

Crea un articolo

Crea un ricambio o una voce di manodopera. unit_type deve essere coerente con il tipo: kg, L, kit, pz per il magazzino; gg, h, lav, min per la manodopera. vat_code deve essere una delle aliquote attive dell'azienda (vedi GET /v1/vat-rates).
dalla revisione 2026-10-04

Accetta work_category_ids (massimo 10, nell'ordine scelto): assente lascia invariate le categorie dell'articolo, [] o null li rimuove. La risposta include work_category_ids e work_categories.

Risposte
201
L'articolo creato.
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.
409
Un altro articolo dello stesso tipo (magazzino o manodopera) usa già questo codice, senza distinguere maiuscole e spazi iniziali o finali. Il suo id è in `candidates`. Vale per tutte le revisioni supportate.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl -X POST https://api.officina.it/v1/articles \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Filtro olio",
  "code": "FO-2231",
  "unit_type": "pz",
  "stock": 12,
  "purchase_price": 6.4,
  "sale_price": 14.9,
  "vat_code": "22",
  "supplier_id": null
}'
Risposta
{
  "object": "article",
  "id": "f18c4b62-9d07-4e53-a294-6b1f8d3c5e70",
  "code": "FO-2231",
  "name": "Filtro olio",
  "kind": "item",
  "unit_type": "pz",
  "stock": 12,
  "sale_price": 14.9,
  "vat_code": "22",
  "unit_discount_rate": 0,
  "minimum_stock": 4,
  "purchase_price": 6.4,
  "location": "Scaffale A2",
  "comments": "Compatibile con motori 1.2 FIRE",
  "supplier_id": "6f2b8c14-9d70-4a35-b8e2-1c5f7a3d9e60",
  "supplier_name": "Ricambi Lombardia S.r.l."
}
GET /v1/articles/{id}
Permesso richiesto articles.read

Recupera un articolo

Restituisce l'articolo con i campi di dettaglio che l'elenco omette: soglia di riordino, prezzo di acquisto, posizione, note e fornitore.
dalla revisione 2026-10-04

Nuovi campi work_category_ids e work_categories: le categorie per cui si usa l'articolo.

Risposte
200
L'articolo richiesto.
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/articles/{id} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "article",
  "id": "f18c4b62-9d07-4e53-a294-6b1f8d3c5e70",
  "code": "FO-2231",
  "name": "Filtro olio",
  "kind": "item",
  "unit_type": "pz",
  "stock": 12,
  "sale_price": 14.9,
  "vat_code": "22",
  "unit_discount_rate": 0,
  "minimum_stock": 4,
  "purchase_price": 6.4,
  "location": "Scaffale A2",
  "comments": "Compatibile con motori 1.2 FIRE",
  "supplier_id": "6f2b8c14-9d70-4a35-b8e2-1c5f7a3d9e60",
  "supplier_name": "Ricambi Lombardia S.r.l."
}
PATCH /v1/articles/{id}
Permesso richiesto articles.write

Aggiorna un articolo

Il corpo è lo stesso della creazione: va inviato l'oggetto completo, non solo i campi da cambiare. I campi omessi vengono azzerati, non lasciati invariati. Per correggere la giacenza senza annullare le vendite registrate nel frattempo, invia insieme a stock la giacenza letta prima della modifica in loaded_stock: viene applicata la differenza stock - loaded_stock, registrata come movimento di magazzino. Senza loaded_stock, stock è la nuova giacenza. Header If-Match con il campo version letto nell'articolo: obbligatorio dalla revisione 2026-10-22, e prima con loaded_stock (altrimenti 422). Se l'articolo è stato salvato nel frattempo (anche da una ripetizione di questa stessa richiesta) la modifica è rifiutata con 409 e nulla viene salvato. Le vendite e gli altri movimenti di magazzino non cambiano version; il carico di un ordine fornitore sì, perché aggiorna anche il prezzo d'acquisto. Un articolo resta del suo kind per sempre: un unit_type dell'altro tipo (es. da pz a h) è rifiutato con 422 su /unit_type.
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.

dalla revisione 2026-10-04

Accetta work_category_ids (massimo 10, nell'ordine scelto): assente lascia invariate le categorie dell'articolo, [] o null li rimuove. La risposta include work_category_ids e work_categories.

Risposte
200
L'articolo aggiornato.
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
Un altro articolo dello stesso tipo (magazzino o manodopera) usa già questo codice, senza distinguere maiuscole e spazi iniziali o finali. Il suo id è in `candidates`. Vale per tutte le revisioni supportate.
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/articles/{id} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Filtro olio",
  "code": "FO-2231",
  "unit_type": "pz",
  "stock": 12,
  "purchase_price": 6.4,
  "sale_price": 14.9,
  "vat_code": "22",
  "supplier_id": null
}'
Risposta
{
  "object": "article",
  "id": "f18c4b62-9d07-4e53-a294-6b1f8d3c5e70",
  "code": "FO-2231",
  "name": "Filtro olio",
  "kind": "item",
  "unit_type": "pz",
  "stock": 12,
  "sale_price": 14.9,
  "vat_code": "22",
  "unit_discount_rate": 0,
  "minimum_stock": 4,
  "purchase_price": 6.4,
  "location": "Scaffale A2",
  "comments": "Compatibile con motori 1.2 FIRE",
  "supplier_id": "6f2b8c14-9d70-4a35-b8e2-1c5f7a3d9e60",
  "supplier_name": "Ricambi Lombardia S.r.l."
}
DELETE /v1/articles/{id}
Permesso richiesto articles.write

Elimina un articolo

Eliminazione logica: l'articolo sparisce dal catalogo. Le righe dei documenti che lo citano restano intatte.
Risposte
200
L'articolo eliminato.
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/articles/{id} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "article",
  "id": "f18c4b62-9d07-4e53-a294-6b1f8d3c5e70",
  "code": "FO-2231",
  "name": "Filtro olio",
  "kind": "item",
  "unit_type": "pz",
  "stock": 12,
  "sale_price": 14.9,
  "vat_code": "22",
  "unit_discount_rate": 0,
  "minimum_stock": 4,
  "purchase_price": 6.4,
  "location": "Scaffale A2",
  "comments": "Compatibile con motori 1.2 FIRE",
  "supplier_id": "6f2b8c14-9d70-4a35-b8e2-1c5f7a3d9e60",
  "supplier_name": "Ricambi Lombardia S.r.l."
}
GET /v1/articles/{id}/movements
Permesso richiesto articles.read

Movimenti di un articolo

Lo storico di carico e scarico dell'articolo. quantity è positiva per i carichi e negativa per gli scarichi; source indica il documento che ha generato il movimento e source_id lo identifica.
dalla revisione 2026-10-13

Paginazione: limit (predefinito 20, massimo 100) e starting_after; le voci sono ordinate dalla più recente (per data e id) e next_starting_after porta alla pagina successiva. Prima di questa revisione l'elenco torna intero.

Risposte
200
I movimenti dell'articolo.
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/articles/{id}/movements \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "data": [
    {
      "object": "article_movement",
      "id": "8b4d2f06-1c73-4a95-b028-5e7f3a1d9c64",
      "quantity": -4,
      "source": "worksheet",
      "source_id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
      "seq_number": 412,
      "document_date": "2026-07-15",
      "customer_name": "Mario Rossi",
      "vehicle_name": "Fiat Panda",
      "total": 74.0,
      "created_at": "2026-07-15T08:31:00Z"
    },
    {
      "object": "article_movement",
      "id": "3f7a9c25-6d81-4e40-9b53-2a8c1f4d7e06",
      "quantity": 20,
      "source": "delivery_note",
      "source_id": "9d1e6b48-5c20-4f37-a814-3b7e2d9f5a61",
      "seq_number": 77,
      "document_date": "2026-07-02",
      "customer_name": null,
      "vehicle_name": null,
      "total": 128.0,
      "created_at": "2026-07-02T11:14:00Z"
    }
  ],
  "has_more": false,
  "url": "/v1/articles/f18c4b62-9d07-4e53-a294-6b1f8d3c5e70/movements"
}
GET /v1/vat-rates
Permesso richiesto settings.read

Elenca le aliquote IVA

Le aliquote attive dell'azienda, da usare per valorizzare vat_code sugli articoli e sulle righe dei documenti. È una voce di Impostazioni, quindi richiede il permesso settings.read.
Risposte
200
Le aliquote IVA attive.
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/vat-rates \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "data": [
    {
      "object": "vat_rate",
      "code": "22",
      "rate": 22,
      "description": "Aliquota ordinaria"
    },
    {
      "object": "vat_rate",
      "code": "10",
      "rate": 10,
      "description": "Aliquota ridotta"
    },
    {
      "object": "vat_rate",
      "code": "N2.2",
      "rate": 0,
      "description": "Non soggetta"
    }
  ],
  "has_more": false,
  "url": "/v1/vat-rates"
}