Schede lavoro

Schede, righe, pagamenti, stati di lavorazione e marcatempo.

22 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/time-entries
Permesso richiesto worksheets.read

Elenca i tempi registrati

I tempi registrati col Marcatempo su tutte le schede lavoro, dal più recente per ora di inizio: timer accesi e fermati e tempi inseriti a mano, di tutti i collaboratori. Serve per portare le ore lavorate in un foglio presenze, in un gestionale paghe o in un'analisi della resa. from e to sono giorni (AAAA-MM-GG, ora di Roma), entrambi inclusi, e filtrano sull'ora di inizio; to prima di from risponde 422 con param: /to. worksheet_id limita a una scheda, user_id a un collaboratore. I tempi delle schede eliminate non compaiono. Un timer acceso ha running: true, ended_at: null e la durata contata fino al momento della risposta. I tempi di attesa (user: null, tipo con is_wait: true) non sono ore lavorate. Serve il modulo Marcatempo attivo (403 altrimenti).
dalla revisione 2026-10-25

Nuovo endpoint: i tempi registrati col Marcatempo in un periodo, con filtri per scheda e collaboratore.

Risposte
200
Una pagina di tempi, dal più recente.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
Il modulo Marcatempo non è attivo (Impostazioni → Moduli), oppure la chiave non ha il permesso `worksheets.read`.
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/time-entries \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "data": [
    {
      "object": "time_entry",
      "id": "4e9a0c17-3b5d-4a82-9f6e-2c1b7d8e5a93",
      "worksheet_id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
      "time_type_id": "7f4c1b98-2d6e-4a35-9c81-0e5b3a7d2f14",
      "user": null,
      "started_at": "2026-10-23T08:30:00Z",
      "ended_at": "2026-10-23T09:30:00Z",
      "duration_seconds": 3600,
      "running": false,
      "note": "Pastiglie in arrivo dal fornitore",
      "source": "manual",
      "forgotten": false,
      "suggested_stop_at": null,
      "can_edit": true,
      "can_stop": false,
      "can_discard": false
    },
    {
      "object": "time_entry",
      "id": "1f6b3d82-7a9c-4e05-b1d4-6e8a2c9f0b37",
      "worksheet_id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
      "time_type_id": "3b8e2f71-6c4a-4d19-9e05-7a1c2d3e4f60",
      "user": {
        "object": "time_person",
        "id": "2f3e4d5c-6b7a-4980-8f1e-2d3c4b5a6978",
        "first_name": "Marco",
        "last_name": "Esposito"
      },
      "started_at": "2026-10-23T07:00:00Z",
      "ended_at": "2026-10-23T08:30:00Z",
      "duration_seconds": 5400,
      "running": false,
      "note": "Smontaggio freni anteriori",
      "source": "timer",
      "forgotten": false,
      "suggested_stop_at": null,
      "can_edit": true,
      "can_stop": false,
      "can_discard": false
    }
  ],
  "has_more": true,
  "next_starting_after": "eyJ0IjoiMjAyNi0xMC0yM1QwNzowMDowMFoiLCJpIjoiMWY2YjNkODItN2E5Yy00ZTA1LWIxZDQtNmU4YTJjOWYwYjM3In0",
  "url": "/v1/time-entries"
}
GET /v1/time-types
Permesso richiesto worksheets.read

Elenca i tipi di tempo

I tipi di tempo del Marcatempo, nell'ordine di Impostazioni → Tempi. Un'officina che non ha mai usato il Marcatempo non ha ancora tipi: l'elenco è vuoto (una lettura via API non crea nulla; il primo tipo, Lavorazione, nasce quando l'officina apre il Marcatempo). Un tipo di lavoro (is_wait: false) è il timer di una persona e conta nelle ore lavorate. Un tipo di attesa (is_wait: true) è il tempo della scheda senza una persona, per esempio l'auto ferma in attesa dei ricambi: si registra ma non conta mai come lavorato. Serve il modulo Marcatempo attivo in Impostazioni → Moduli: se è spento la risposta è 403 forbidden. Elenco completo in una sola pagina (has_more è sempre false).
dalla revisione 2026-10-25

Nuovo endpoint: i tipi di tempo del Marcatempo dell'officina.

Risposte
200
I tipi di tempo, in ordine.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
Il modulo Marcatempo non è attivo (Impostazioni → Moduli), oppure la chiave non ha il permesso `worksheets.read`.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl https://api.officina.it/v1/time-types \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "has_more": false,
  "url": "/v1/time-types",
  "data": [
    {
      "object": "time_type",
      "id": "3b8e2f71-6c4a-4d19-9e05-7a1c2d3e4f60",
      "name": "Lavorazione",
      "is_wait": false,
      "position": 0
    },
    {
      "object": "time_type",
      "id": "5d0a9c32-1e7b-4f86-b3a4-8c2e6f1d9b07",
      "name": "Diagnosi",
      "is_wait": false,
      "position": 1
    },
    {
      "object": "time_type",
      "id": "7f4c1b98-2d6e-4a35-9c81-0e5b3a7d2f14",
      "name": "Attesa ricambi",
      "is_wait": true,
      "position": 2
    }
  ]
}
GET /v1/work-categories
Permesso richiesto settings.read

Elenca le categorie

Le categorie configurate dall'officina, da usare per valorizzare work_category_id. È una voce di Impostazioni, quindi richiede il permesso settings.read.
Risposte
200
Le categorie configurate.
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/work-categories \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "data": [
    {
      "object": "work_category",
      "id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
      "name": "Tagliando"
    },
    {
      "object": "work_category",
      "id": "5f2b7d94-1a63-48ec-9207-8d4e3c1f6a52",
      "name": "Freni"
    }
  ],
  "has_more": false,
  "url": "/v1/work-categories"
}
GET /v1/worksheets
Permesso richiesto worksheets.read

Elenca le schede lavoro

Le schede lavoro dell'officina, dalla più recente. Filtra per stato con status, per cliente con customer_id, per veicolo con vehicle_id e per periodo con from / to. La paginazione usa un cursore opaco: passa next_starting_after invariato in starting_after e fermati quando has_more è false.
dalla revisione 2026-10-03

Nuovi campi work_category_ids e work_categories: tutte le categorie del documento, nell'ordine scelto (work_category_id riporta il primo, per i client che ne gestiscono uno solo).

Risposte
200
Una pagina di schede lavoro.
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.
415
Il Content-Type deve essere application/json e Accept deve accettare JSON.
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/worksheets \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "data": [
    {
      "object": "worksheet",
      "id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
      "seq_number": 412,
      "status": "started",
      "title": "Tagliando 60.000 km",
      "customer_id": "4c911f08-7713-4e83-bdf6-a0692a1b43fd",
      "customer_name": "Mario Rossi",
      "vehicle_id": "8821f0ac-5d2b-41e7-9a10-6c3f2b7d4e55",
      "vehicle_name": "Fiat Panda",
      "vehicle_license": "AB123CD",
      "work_category_id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
      "work_category_name": "Tagliando",
      "work_category_ids": [
        "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40"
      ],
      "work_categories": [
        {
          "object": "work_category",
          "id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
          "name": "Tagliando"
        }
      ],
      "km": 61240,
      "total_before_tax": 233.9,
      "total_tax": 51.46,
      "total_after_tax": 285.36,
      "total_discount": 0,
      "total_payments": 150.0,
      "outstanding_payments": 135.36,
      "fiscal_document_type": "fattura",
      "frozen": false,
      "invoice_id": null,
      "receipt_id": null,
      "started_at": "2026-07-15T08:30:00Z",
      "completed_at": null,
      "delivered_at": null,
      "created_at": "2026-07-15T08:12:00Z",
      "updated_at": "2026-07-16T10:02:00Z"
    }
  ],
  "has_more": true,
  "next_starting_after": "eyJvIjoyMH0",
  "url": "/v1/worksheets",
  "date_filter": {
    "object": "date_filter",
    "preset": "year",
    "from": "2026-01-01",
    "to": "2026-12-31"
  }
}
POST /v1/worksheets
Permesso richiesto worksheets.write

Crea una scheda lavoro

Crea una scheda lavoro in stato draft. Il numero progressivo (seq_number) è assegnato dal server. Le righe non si passano qui: crea la scheda, poi aggiungile con POST /v1/worksheets/{id}/line-items/batch.
dalla revisione 2026-10-03

Accetta work_category_ids per impostare più categorie (massimo 10); la risposta include work_category_ids e work_categories. work_category_id resta valido con il significato di sempre.

Risposte
201
La scheda lavoro creata.
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.
415
Il Content-Type deve essere application/json e Accept deve accettare JSON.
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/worksheets \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31" \
  -H "Content-Type: application/json" \
  -d '{
  "customer_id": "4c911f08-7713-4e83-bdf6-a0692a1b43fd",
  "vehicle_id": "8821f0ac-5d2b-41e7-9a10-6c3f2b7d4e55",
  "title": "Tagliando 60.000 km",
  "km": 61240
}'
Risposta
{
  "object": "worksheet",
  "id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
  "seq_number": 412,
  "status": "started",
  "title": "Tagliando 60.000 km",
  "customer_id": "4c911f08-7713-4e83-bdf6-a0692a1b43fd",
  "customer_name": "Mario Rossi",
  "vehicle_id": "8821f0ac-5d2b-41e7-9a10-6c3f2b7d4e55",
  "vehicle_name": "Fiat Panda",
  "vehicle_license": "AB123CD",
  "work_category_id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
  "work_category_name": "Tagliando",
  "work_category_ids": [
    "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40"
  ],
  "work_categories": [
    {
      "object": "work_category",
      "id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
      "name": "Tagliando"
    }
  ],
  "km": 61240,
  "total_before_tax": 233.9,
  "total_tax": 51.46,
  "total_after_tax": 285.36,
  "total_discount": 0,
  "total_payments": 150.0,
  "outstanding_payments": 135.36,
  "fiscal_document_type": "fattura",
  "frozen": false,
  "invoice_id": null,
  "receipt_id": null,
  "started_at": "2026-07-15T08:30:00Z",
  "completed_at": null,
  "delivered_at": null,
  "created_at": "2026-07-15T08:12:00Z",
  "updated_at": "2026-07-16T10:02:00Z"
}
GET /v1/worksheets/by-number/{year}/{number}
Permesso richiesto worksheets.read

Recupera la scheda lavoro dal numero

Restituisce la scheda lavoro con il numero number dell'anno year (anno della data della scheda): 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 scheda lavoro dal numero e dall'anno.

Risposte
200
La scheda lavoro, 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/worksheets/by-number/{year}/{number} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "worksheet",
  "id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
  "seq_number": 412,
  "status": "started",
  "title": "Tagliando 60.000 km",
  "customer_id": "4c911f08-7713-4e83-bdf6-a0692a1b43fd",
  "customer_name": "Mario Rossi",
  "vehicle_id": "8821f0ac-5d2b-41e7-9a10-6c3f2b7d4e55",
  "vehicle_name": "Fiat Panda",
  "vehicle_license": "AB123CD",
  "work_category_id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
  "work_category_name": "Tagliando",
  "work_category_ids": [
    "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40"
  ],
  "work_categories": [
    {
      "object": "work_category",
      "id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
      "name": "Tagliando"
    }
  ],
  "km": 61240,
  "total_before_tax": 233.9,
  "total_tax": 51.46,
  "total_after_tax": 285.36,
  "total_discount": 0,
  "total_payments": 150.0,
  "outstanding_payments": 135.36,
  "fiscal_document_type": "fattura",
  "frozen": false,
  "invoice_id": null,
  "receipt_id": null,
  "started_at": "2026-07-15T08:30:00Z",
  "completed_at": null,
  "delivered_at": null,
  "created_at": "2026-07-15T08:12:00Z",
  "updated_at": "2026-07-16T10:02:00Z",
  "comments": "Sostituire anche il filtro abitacolo.",
  "line_items": [
    {
      "object": "work_line_item",
      "id": "7c0f6c4e-9b1a-4c2e-9a5d-2f3b1e8a4d10",
      "article_id": null,
      "description": "Olio motore 5W30",
      "quantity": 4,
      "unit_type": "pz",
      "unit_price": 18.5,
      "unit_discount_rate": 0,
      "tax_rate": 22,
      "vat_code": "22",
      "total_before_tax": 74.0,
      "total_tax": 16.28,
      "total_after_tax": 90.28,
      "created_at": "2026-07-15T08:31:00Z"
    },
    {
      "object": "work_line_item",
      "id": "0b4a2d6f-1c3e-4f5a-8b9c-7d6e5f4a3b2c",
      "article_id": null,
      "description": "Manodopera tagliando",
      "quantity": 2,
      "unit_type": "pz",
      "unit_price": 79.95,
      "unit_discount_rate": 0,
      "tax_rate": 22,
      "vat_code": "22",
      "total_before_tax": 159.9,
      "total_tax": 35.18,
      "total_after_tax": 195.08,
      "position": 1,
      "created_at": "2026-07-15T08:31:00Z"
    }
  ],
  "documents": []
}
GET /v1/worksheets/status-counts
Permesso richiesto worksheets.read

Conta le schede per stato

Il numero di schede in ciascuno stato, con gli stessi filtri dell'elenco. Serve a popolare i contatori senza scaricare le schede.
Risposte
200
Il numero di schede 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.
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/worksheets/status-counts \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "worksheet_status_counts",
  "draft": 3,
  "waiting": 5,
  "started": 2,
  "completed": 8,
  "delivered": 41,
  "archived": 0,
  "date_filter": {
    "object": "date_filter",
    "preset": "year",
    "from": "2026-01-01",
    "to": "2026-12-31"
  }
}
GET /v1/worksheets/{id}
Permesso richiesto worksheets.read

Recupera una scheda lavoro

Restituisce la scheda con le righe (line_items), i documenti allegati e i totali calcolati. frozen indica che la scheda ha già generato un documento fiscale e non è più modificabile; linked_invoices e linked_receipt puntano ai documenti emessi.
dalla revisione 2026-10-03

Nuovi campi work_category_ids e work_categories: tutte le categorie del documento, nell'ordine scelto (work_category_id riporta il primo, per i client che ne gestiscono uno solo).

Risposte
200
La scheda lavoro 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.
415
Il Content-Type deve essere application/json e Accept deve accettare JSON.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl https://api.officina.it/v1/worksheets/{id} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "worksheet",
  "id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
  "seq_number": 412,
  "status": "started",
  "title": "Tagliando 60.000 km",
  "customer_id": "4c911f08-7713-4e83-bdf6-a0692a1b43fd",
  "customer_name": "Mario Rossi",
  "vehicle_id": "8821f0ac-5d2b-41e7-9a10-6c3f2b7d4e55",
  "vehicle_name": "Fiat Panda",
  "vehicle_license": "AB123CD",
  "work_category_id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
  "work_category_name": "Tagliando",
  "work_category_ids": [
    "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40"
  ],
  "work_categories": [
    {
      "object": "work_category",
      "id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
      "name": "Tagliando"
    }
  ],
  "km": 61240,
  "total_before_tax": 233.9,
  "total_tax": 51.46,
  "total_after_tax": 285.36,
  "total_discount": 0,
  "total_payments": 150.0,
  "outstanding_payments": 135.36,
  "fiscal_document_type": "fattura",
  "frozen": false,
  "invoice_id": null,
  "receipt_id": null,
  "started_at": "2026-07-15T08:30:00Z",
  "completed_at": null,
  "delivered_at": null,
  "created_at": "2026-07-15T08:12:00Z",
  "updated_at": "2026-07-16T10:02:00Z",
  "comments": "Sostituire anche il filtro abitacolo.",
  "line_items": [
    {
      "object": "work_line_item",
      "id": "7c0f6c4e-9b1a-4c2e-9a5d-2f3b1e8a4d10",
      "article_id": null,
      "description": "Olio motore 5W30",
      "quantity": 4,
      "unit_type": "pz",
      "unit_price": 18.5,
      "unit_discount_rate": 0,
      "tax_rate": 22,
      "vat_code": "22",
      "total_before_tax": 74.0,
      "total_tax": 16.28,
      "total_after_tax": 90.28,
      "created_at": "2026-07-15T08:31:00Z"
    },
    {
      "object": "work_line_item",
      "id": "0b4a2d6f-1c3e-4f5a-8b9c-7d6e5f4a3b2c",
      "article_id": null,
      "description": "Manodopera tagliando",
      "quantity": 2,
      "unit_type": "pz",
      "unit_price": 79.95,
      "unit_discount_rate": 0,
      "tax_rate": 22,
      "vat_code": "22",
      "total_before_tax": 159.9,
      "total_tax": 35.18,
      "total_after_tax": 195.08,
      "position": 1,
      "created_at": "2026-07-15T08:31:00Z"
    }
  ],
  "documents": []
}
PATCH /v1/worksheets/{id}
Permesso richiesto worksheets.write

Aggiorna una scheda lavoro

Aggiorna solo i campi presenti nel corpo: gli altri restano invariati, e null svuota il campo. Una scheda frozen (già fatturata) rifiuta la modifica con 409.
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-03

Accetta work_category_ids: sostituisce l'intero elenco delle categorie ([] o null li rimuove tutti). work_category_id continua a sostituire solo il primo dell'elenco. La risposta include work_category_ids e work_categories.

Risposte
200
La scheda lavoro 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
L'operazione è in conflitto con lo stato attuale della risorsa.
415
Il Content-Type deve essere application/json e Accept deve accettare JSON.
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/worksheets/{id} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Tagliando 60.000 km — completato",
  "km": 61310,
  "internal_comments": null
}'
Risposta
{
  "object": "worksheet",
  "id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
  "seq_number": 412,
  "status": "started",
  "title": "Tagliando 60.000 km",
  "customer_id": "4c911f08-7713-4e83-bdf6-a0692a1b43fd",
  "customer_name": "Mario Rossi",
  "vehicle_id": "8821f0ac-5d2b-41e7-9a10-6c3f2b7d4e55",
  "vehicle_name": "Fiat Panda",
  "vehicle_license": "AB123CD",
  "work_category_id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
  "work_category_name": "Tagliando",
  "work_category_ids": [
    "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40"
  ],
  "work_categories": [
    {
      "object": "work_category",
      "id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
      "name": "Tagliando"
    }
  ],
  "km": 61240,
  "total_before_tax": 233.9,
  "total_tax": 51.46,
  "total_after_tax": 285.36,
  "total_discount": 0,
  "total_payments": 150.0,
  "outstanding_payments": 135.36,
  "fiscal_document_type": "fattura",
  "frozen": false,
  "invoice_id": null,
  "receipt_id": null,
  "started_at": "2026-07-15T08:30:00Z",
  "completed_at": null,
  "delivered_at": null,
  "created_at": "2026-07-15T08:12:00Z",
  "updated_at": "2026-07-16T10:02:00Z",
  "comments": "Sostituire anche il filtro abitacolo.",
  "line_items": [
    {
      "object": "work_line_item",
      "id": "7c0f6c4e-9b1a-4c2e-9a5d-2f3b1e8a4d10",
      "article_id": null,
      "description": "Olio motore 5W30",
      "quantity": 4,
      "unit_type": "pz",
      "unit_price": 18.5,
      "unit_discount_rate": 0,
      "tax_rate": 22,
      "vat_code": "22",
      "total_before_tax": 74.0,
      "total_tax": 16.28,
      "total_after_tax": 90.28,
      "created_at": "2026-07-15T08:31:00Z"
    },
    {
      "object": "work_line_item",
      "id": "0b4a2d6f-1c3e-4f5a-8b9c-7d6e5f4a3b2c",
      "article_id": null,
      "description": "Manodopera tagliando",
      "quantity": 2,
      "unit_type": "pz",
      "unit_price": 79.95,
      "unit_discount_rate": 0,
      "tax_rate": 22,
      "vat_code": "22",
      "total_before_tax": 159.9,
      "total_tax": 35.18,
      "total_after_tax": 195.08,
      "position": 1,
      "created_at": "2026-07-15T08:31:00Z"
    }
  ],
  "documents": []
}
DELETE /v1/worksheets/{id}
Permesso richiesto worksheets.write

Elimina una scheda lavoro

Eliminazione logica. Una scheda che ha già generato una fattura o uno scontrino non può essere eliminata: la richiesta risponde 409 finché il documento fiscale esiste.
Risposte
200
Conferma di eliminazione.
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.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl -X DELETE https://api.officina.it/v1/worksheets/{id} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "worksheet",
  "id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
  "seq_number": 412,
  "status": "started",
  "title": "Tagliando 60.000 km",
  "deleted_at": "2026-07-20T11:04:00Z"
}
GET /v1/worksheets/{id}/checkins
Permesso richiesto checkins.read

Accettazioni collegate alla scheda

Le accettazioni da cui la scheda è stata generata. Restituisce accettazioni, quindi richiede il permesso checkins.read e non worksheets.read.
dalla revisione 2026-10-03

Nuovi campi work_category_ids e work_categories: tutte le categorie del documento, nell'ordine scelto (work_category_id riporta il primo, per i client che ne gestiscono uno solo).

Risposte
200
Le accettazioni collegate alla scheda.
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/worksheets/{id}/checkins \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "data": [
    {
      "object": "checkin",
      "id": "1c7a9e04-5f83-4b26-8d10-6e2b4a9c7f31",
      "status": "convertita",
      "vehicle_id": "8821f0ac-5d2b-41e7-9a10-6c3f2b7d4e55",
      "customer_id": "4c911f08-7713-4e83-bdf6-a0692a1b43fd",
      "created_at": "2026-07-15T07:55:00Z"
    }
  ],
  "has_more": false,
  "url": "/v1/worksheets/a5d21e64-8f37-4b90-ae12-3c7d6b048f95/checkins"
}
POST /v1/worksheets/{id}/documents
Permesso richiesto worksheets.write

Allega un documento alla scheda

Carica un file fra i documenti della scheda. La richiesta è multipart/form-data con il file nel campo file, non JSON.
Risposte
201
Il documento allegato.
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.
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/worksheets/{id}/documents \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31" \
  -F "file=@/percorso/documento.pdf"
Risposta
{
  "object": "worksheet_document",
  "id": "6b3e9f10-2c84-4d57-91ab-5e8f0a2d7c63",
  "name": "preventivo-firmato.pdf",
  "content_type": "application/pdf",
  "description": "Preventivo firmato",
  "file_size_bytes": 92418,
  "url": "/v1/worksheets/a5d21e64-8f37-4b90-ae12-3c7d6b048f95/documents/6b3e9f10-2c84-4d57-91ab-5e8f0a2d7c63/download",
  "created_at": "2026-07-15T09:40:00Z"
}
DELETE /v1/worksheets/{id}/documents/{documentID}
Permesso richiesto worksheets.write

Elimina un documento della scheda

Rimuove definitivamente il file allegato.
Risposte
200
Conferma di eliminazione.
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/worksheets/{id}/documents/{documentID} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "worksheet_document",
  "id": "6b3e9f10-2c84-4d57-91ab-5e8f0a2d7c63",
  "name": "preventivo-firmato.pdf",
  "content_type": "application/pdf",
  "file_size_bytes": 92418,
  "created_at": "2026-07-15T09:40:00Z"
}
GET /v1/worksheets/{id}/documents/{documentID}/download
Permesso richiesto worksheets.read

Scarica un documento della scheda

Restituisce il contenuto del file, non JSON. È il percorso indicato dal campo url di ogni documento.
Risposte
200
success
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/worksheets/{id}/documents/{documentID}/download \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
POST /v1/worksheets/{id}/line-items/batch
Permesso richiesto worksheets.write

Modifica le righe in blocco

Aggiunge, aggiorna, rimuove e riordina le righe in una sola richiesta, applicata come singola transazione: se una operazione fallisce non viene applicata nessuna. I totali della scheda vengono ricalcolati e restituiti. Collega una riga al magazzino valorizzando article_id; lasciandolo null la riga resta libera.
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 scheda con le righe aggiornate e i totali ricalcolati.
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.
415
Il Content-Type deve essere application/json e Accept deve accettare JSON.
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 POST https://api.officina.it/v1/worksheets/{id}/line-items/batch \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31" \
  -H "Content-Type: application/json" \
  -d '{
  "add": [
    {
      "description": "Brake pads (front)",
      "quantity": 1,
      "unit_type": "kit",
      "unit_price": 89.9,
      "unit_discount_rate": 0,
      "vat_code": "22",
      "article_id": null
    }
  ],
  "update": [
    {
      "id": "7c0f6c4e-9b1a-4c2e-9a5d-2f3b1e8a4d10",
      "description": "Labour — brake service",
      "quantity": 1.5,
      "unit_type": "pz",
      "unit_price": 40,
      "unit_discount_rate": 10,
      "vat_code": "22"
    }
  ],
  "remove": [
    "0b4a2d6f-1c3e-4f5a-8b9c-7d6e5f4a3b2c"
  ],
  "reorder": [
    {
      "id": "9d8c7b6a-5f4e-3d2c-1b0a-9e8d7c6b5a40",
      "position": 1
    }
  ]
}'
Risposta
{
  "object": "worksheet",
  "id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
  "seq_number": 412,
  "status": "started",
  "title": "Tagliando 60.000 km",
  "customer_id": "4c911f08-7713-4e83-bdf6-a0692a1b43fd",
  "customer_name": "Mario Rossi",
  "vehicle_id": "8821f0ac-5d2b-41e7-9a10-6c3f2b7d4e55",
  "vehicle_name": "Fiat Panda",
  "vehicle_license": "AB123CD",
  "work_category_id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
  "work_category_name": "Tagliando",
  "work_category_ids": [
    "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40"
  ],
  "work_categories": [
    {
      "object": "work_category",
      "id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
      "name": "Tagliando"
    }
  ],
  "km": 61240,
  "total_before_tax": 233.9,
  "total_tax": 51.46,
  "total_after_tax": 285.36,
  "total_discount": 0,
  "total_payments": 150.0,
  "outstanding_payments": 135.36,
  "fiscal_document_type": "fattura",
  "frozen": false,
  "invoice_id": null,
  "receipt_id": null,
  "started_at": "2026-07-15T08:30:00Z",
  "completed_at": null,
  "delivered_at": null,
  "created_at": "2026-07-15T08:12:00Z",
  "updated_at": "2026-07-16T10:02:00Z",
  "comments": "Sostituire anche il filtro abitacolo.",
  "line_items": [
    {
      "object": "work_line_item",
      "id": "7c0f6c4e-9b1a-4c2e-9a5d-2f3b1e8a4d10",
      "article_id": null,
      "description": "Olio motore 5W30",
      "quantity": 4,
      "unit_type": "pz",
      "unit_price": 18.5,
      "unit_discount_rate": 0,
      "tax_rate": 22,
      "vat_code": "22",
      "total_before_tax": 74.0,
      "total_tax": 16.28,
      "total_after_tax": 90.28,
      "created_at": "2026-07-15T08:31:00Z"
    },
    {
      "object": "work_line_item",
      "id": "0b4a2d6f-1c3e-4f5a-8b9c-7d6e5f4a3b2c",
      "article_id": null,
      "description": "Manodopera tagliando",
      "quantity": 2,
      "unit_type": "pz",
      "unit_price": 79.95,
      "unit_discount_rate": 0,
      "tax_rate": 22,
      "vat_code": "22",
      "total_before_tax": 159.9,
      "total_tax": 35.18,
      "total_after_tax": 195.08,
      "position": 1,
      "created_at": "2026-07-15T08:31:00Z"
    }
  ],
  "documents": []
}
GET /v1/worksheets/{id}/payments
Permesso richiesto worksheets.read

Elenca i pagamenti della scheda

Gli incassi registrati sulla scheda. Il residuo da incassare è outstanding_payments sulla scheda stessa.
Risposte
200
I pagamenti della scheda.
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/worksheets/{id}/payments \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "list",
  "data": [
    {
      "object": "payment",
      "id": "d47c0b58-3e91-42a6-8f05-1b9d6a3e2c74",
      "amount": 150.0,
      "payment_method": "MP01",
      "payment_date": "2026-07-16",
      "created_at": "2026-07-16T10:02:00Z"
    }
  ],
  "has_more": false,
  "url": "/v1/worksheets/a5d21e64-8f37-4b90-ae12-3c7d6b048f95/payments"
}
POST /v1/worksheets/{id}/payments
Permesso richiesto worksheets.write

Registra un pagamento

Registra un incasso sulla scheda. payment_method usa i codici ministeriali (MP01 contanti, MP02 assegno, MP05 bonifico, MP08 carta). L'importo può essere parziale: registra più pagamenti fino a coprire il totale.
Risposte
201
Il pagamento registrato.
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.
415
Il Content-Type deve essere application/json e Accept deve accettare JSON.
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/worksheets/{id}/payments \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31" \
  -H "Content-Type: application/json" \
  -d '{
  "amount": 150.0,
  "payment_method": "MP01",
  "payment_date": "2026-07-16"
}'
Risposta
{
  "object": "payment",
  "id": "d47c0b58-3e91-42a6-8f05-1b9d6a3e2c74",
  "amount": 150.0,
  "payment_method": "MP01",
  "payment_date": "2026-07-16",
  "created_at": "2026-07-16T10:02:00Z"
}
DELETE /v1/worksheets/{id}/payments/{paymentID}
Permesso richiesto worksheets.write

Elimina un pagamento

Rimuove l'incasso e riporta il residuo della scheda al valore precedente.
Risposte
200
Conferma di eliminazione.
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/worksheets/{id}/payments/{paymentID} \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "payment",
  "id": "d47c0b58-3e91-42a6-8f05-1b9d6a3e2c74",
  "amount": 150.0,
  "payment_method": "MP01",
  "payment_date": "2026-07-16",
  "created_at": "2026-07-16T10:02:00Z"
}
GET /v1/worksheets/{id}/time
Permesso richiesto worksheets.read

Recupera i tempi di una scheda

La scheda Marcatempo di una scheda lavoro, come la vede il titolare: tutti i tempi registrati (prima i timer accesi, poi dal più recente), i timer accesi dei collaboratori e il riepilogo. Il riepilogo (summary) confronta le ore lavorate con le ore fatturate in manodopera: righe in ore (h), minuti (min) o giorni (gg, con le ore di una giornata di day_hours). Le righe a corpo (lav) non hanno un tempo misurabile e sono contate a parte in flat_rate_lines. difference_minutes è fatturato meno lavorato, resa_percent il fatturato sul lavorato (null prima di un minuto di lavoro), labor_revenue e revenue_per_hour il ricavo della manodopera, imponibile, e il ricavo per ora lavorata. Il tempo di attesa (wait_minutes) non conta mai come lavorato. people riporta le ore per collaboratore con la quota sul totale, type_totals le ore per tipo, billed_lines le righe di manodopera usate per il fatturato. Con l'API la chiave agisce come il titolare: la risposta è sempre il quadro completo (full_picture: true) ed è in sola lettura, quindi timers e assignees sono sempre vuoti, can_add, can_add_wait e i flag can_* dei tempi sempre false, e colleagues elenca ogni timer di lavoro in corso sulla scheda, compreso quello del titolare. Avviare, fermare e correggere i tempi resta nell'app. locked: true indica che il piano non include la registrazione dei tempi; quanto registrato resta leggibile. Serve il modulo Marcatempo attivo (403 altrimenti). Una scheda eliminata o di un'altra officina risponde 404.
dalla revisione 2026-10-25

Nuovo endpoint: il Marcatempo di una scheda lavoro, con ore lavorate, ore fatturate, differenza e resa.

Risposte
200
I tempi della scheda con il riepilogo.
401
Chiave API mancante, non valida, revocata o scaduta.
402
Il piano non include l'accesso API, oppure non è attivo un abbonamento.
403
Il modulo Marcatempo non è attivo (Impostazioni → Moduli), oppure la chiave non ha il permesso `worksheets.read`.
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/worksheets/{id}/time \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "worksheet_times",
  "worksheet_id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
  "now": "2026-10-23T10:30:00Z",
  "closed": false,
  "locked": false,
  "full_picture": true,
  "can_add": false,
  "can_add_wait": false,
  "day_hours": 8,
  "notice": null,
  "time_types": [
    {
      "object": "time_type",
      "id": "3b8e2f71-6c4a-4d19-9e05-7a1c2d3e4f60",
      "name": "Lavorazione",
      "is_wait": false,
      "position": 0
    },
    {
      "object": "time_type",
      "id": "7f4c1b98-2d6e-4a35-9c81-0e5b3a7d2f14",
      "name": "Attesa ricambi",
      "is_wait": true,
      "position": 1
    }
  ],
  "timers": [],
  "colleagues": [
    {
      "object": "time_entry",
      "id": "9c2e7a51-0b4d-4f68-a3e9-1d7c5b2f8a40",
      "worksheet_id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
      "time_type_id": "3b8e2f71-6c4a-4d19-9e05-7a1c2d3e4f60",
      "user": {
        "object": "time_person",
        "id": "2f3e4d5c-6b7a-4980-8f1e-2d3c4b5a6978",
        "first_name": "Marco",
        "last_name": "Esposito"
      },
      "started_at": "2026-10-23T09:45:00Z",
      "ended_at": null,
      "duration_seconds": 2700,
      "running": true,
      "note": "",
      "source": "timer",
      "forgotten": false,
      "suggested_stop_at": null,
      "can_edit": false,
      "can_stop": false,
      "can_discard": false
    }
  ],
  "entries": [
    {
      "object": "time_entry",
      "id": "9c2e7a51-0b4d-4f68-a3e9-1d7c5b2f8a40",
      "worksheet_id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
      "time_type_id": "3b8e2f71-6c4a-4d19-9e05-7a1c2d3e4f60",
      "user": {
        "object": "time_person",
        "id": "2f3e4d5c-6b7a-4980-8f1e-2d3c4b5a6978",
        "first_name": "Marco",
        "last_name": "Esposito"
      },
      "started_at": "2026-10-23T09:45:00Z",
      "ended_at": null,
      "duration_seconds": 2700,
      "running": true,
      "note": "",
      "source": "timer",
      "forgotten": false,
      "suggested_stop_at": null,
      "can_edit": false,
      "can_stop": false,
      "can_discard": false
    },
    {
      "object": "time_entry",
      "id": "4e9a0c17-3b5d-4a82-9f6e-2c1b7d8e5a93",
      "worksheet_id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
      "time_type_id": "7f4c1b98-2d6e-4a35-9c81-0e5b3a7d2f14",
      "user": null,
      "started_at": "2026-10-23T08:30:00Z",
      "ended_at": "2026-10-23T09:30:00Z",
      "duration_seconds": 3600,
      "running": false,
      "note": "Pastiglie in arrivo dal fornitore",
      "source": "manual",
      "forgotten": false,
      "suggested_stop_at": null,
      "can_edit": false,
      "can_stop": false,
      "can_discard": false
    },
    {
      "object": "time_entry",
      "id": "1f6b3d82-7a9c-4e05-b1d4-6e8a2c9f0b37",
      "worksheet_id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
      "time_type_id": "3b8e2f71-6c4a-4d19-9e05-7a1c2d3e4f60",
      "user": {
        "object": "time_person",
        "id": "2f3e4d5c-6b7a-4980-8f1e-2d3c4b5a6978",
        "first_name": "Marco",
        "last_name": "Esposito"
      },
      "started_at": "2026-10-23T07:00:00Z",
      "ended_at": "2026-10-23T08:30:00Z",
      "duration_seconds": 5400,
      "running": false,
      "note": "Smontaggio freni anteriori",
      "source": "timer",
      "forgotten": false,
      "suggested_stop_at": null,
      "can_edit": false,
      "can_stop": false,
      "can_discard": false
    }
  ],
  "summary": {
    "object": "time_summary",
    "worked_minutes": 135,
    "billed_minutes": 120,
    "wait_minutes": 60,
    "difference_minutes": -15,
    "flat_rate_lines": 1,
    "resa_percent": 89,
    "labor_revenue": 125,
    "revenue_per_hour": 55.56,
    "includes_running": true
  },
  "people": [
    {
      "object": "time_person_total",
      "user": {
        "object": "time_person",
        "id": "2f3e4d5c-6b7a-4980-8f1e-2d3c4b5a6978",
        "first_name": "Marco",
        "last_name": "Esposito"
      },
      "worked_minutes": 135,
      "share_percent": 100,
      "running": true
    }
  ],
  "type_totals": [
    {
      "object": "time_type_total",
      "time_type_id": "3b8e2f71-6c4a-4d19-9e05-7a1c2d3e4f60",
      "total_minutes": 135,
      "running": true
    },
    {
      "object": "time_type_total",
      "time_type_id": "7f4c1b98-2d6e-4a35-9c81-0e5b3a7d2f14",
      "total_minutes": 60,
      "running": false
    }
  ],
  "billed_lines": [
    {
      "object": "time_billed_line",
      "description": "Sostituzione pastiglie freni anteriori",
      "quantity": 2,
      "unit_type": "h",
      "minutes": 120
    },
    {
      "object": "time_billed_line",
      "description": "Tagliando completo",
      "quantity": 1,
      "unit_type": "lav",
      "minutes": null
    }
  ],
  "assignees": []
}
POST /v1/worksheets/{id}/transitions
Permesso richiesto worksheets.write

Cambia stato alla scheda

Applica una transizione di stato e registra la data corrispondente (started_at, completed_at, delivered_at). È il modo corretto di far avanzare una scheda: non impostare status via PATCH, perché non aggiornerebbe le date.
Risposte
200
La scheda dopo la transizione.
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.
415
Il Content-Type deve essere application/json e Accept deve accettare JSON.
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/worksheets/{id}/transitions \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31" \
  -H "Content-Type: application/json" \
  -d '{
  "action": "started"
}'
Risposta
{
  "object": "worksheet",
  "id": "a5d21e64-8f37-4b90-ae12-3c7d6b048f95",
  "seq_number": 412,
  "status": "started",
  "title": "Tagliando 60.000 km",
  "customer_id": "4c911f08-7713-4e83-bdf6-a0692a1b43fd",
  "customer_name": "Mario Rossi",
  "vehicle_id": "8821f0ac-5d2b-41e7-9a10-6c3f2b7d4e55",
  "vehicle_name": "Fiat Panda",
  "vehicle_license": "AB123CD",
  "work_category_id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
  "work_category_name": "Tagliando",
  "work_category_ids": [
    "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40"
  ],
  "work_categories": [
    {
      "object": "work_category",
      "id": "3a8e5c21-9d76-4f03-b418-2c6a9e7d5b40",
      "name": "Tagliando"
    }
  ],
  "km": 61240,
  "total_before_tax": 233.9,
  "total_tax": 51.46,
  "total_after_tax": 285.36,
  "total_discount": 0,
  "total_payments": 150.0,
  "outstanding_payments": 135.36,
  "fiscal_document_type": "fattura",
  "frozen": false,
  "invoice_id": null,
  "receipt_id": null,
  "started_at": "2026-07-15T08:30:00Z",
  "completed_at": null,
  "delivered_at": null,
  "created_at": "2026-07-15T08:12:00Z",
  "updated_at": "2026-07-16T10:02:00Z",
  "comments": "Sostituire anche il filtro abitacolo.",
  "line_items": [
    {
      "object": "work_line_item",
      "id": "7c0f6c4e-9b1a-4c2e-9a5d-2f3b1e8a4d10",
      "article_id": null,
      "description": "Olio motore 5W30",
      "quantity": 4,
      "unit_type": "pz",
      "unit_price": 18.5,
      "unit_discount_rate": 0,
      "tax_rate": 22,
      "vat_code": "22",
      "total_before_tax": 74.0,
      "total_tax": 16.28,
      "total_after_tax": 90.28,
      "created_at": "2026-07-15T08:31:00Z"
    },
    {
      "object": "work_line_item",
      "id": "0b4a2d6f-1c3e-4f5a-8b9c-7d6e5f4a3b2c",
      "article_id": null,
      "description": "Manodopera tagliando",
      "quantity": 2,
      "unit_type": "pz",
      "unit_price": 79.95,
      "unit_discount_rate": 0,
      "tax_rate": 22,
      "vat_code": "22",
      "total_before_tax": 159.9,
      "total_tax": 35.18,
      "total_after_tax": 195.08,
      "position": 1,
      "created_at": "2026-07-15T08:31:00Z"
    }
  ],
  "documents": []
}
GET /v1/worksheets/{id}/waste-disposal
Permesso richiesto worksheets.read

Anteprima smaltimento rifiuti

Dice se lo smaltimento rifiuti si può applicare alla scheda lavoro e quanto vale (importo netto, prima dell'IVA), secondo le impostazioni waste_disposal_* dell'officina. reason spiega perché non è applicabile: disabled, already_applied, nothing_to_charge, fully_paid (scheda già interamente pagata) o frozen.
dalla revisione 2026-10-06

Nuovo endpoint.

Risposte
200
L'anteprima dell'addebito.
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/worksheets/{id}/waste-disposal \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"
Risposta
{
  "object": "waste_disposal_preview",
  "applicable": true,
  "reason": null,
  "rate": 1.2,
  "base": "articles",
  "description": "Smaltimento rifiuti",
  "amount": 2.5
}
POST /v1/worksheets/{id}/waste-disposal
Permesso richiesto worksheets.write

Applica smaltimento rifiuti

Aggiunge la riga di smaltimento rifiuti (quantità 1, unità lav, aliquota IVA predefinita dell'officina, in fondo al documento), ricalcola i totali e restituisce il documento aggiornato. La riga si aggiunge una sola volta: se non è applicabile la risposta è 409 waste_disposal_not_applicable con il motivo in error.reason (anche fully_paid se la scheda è già interamente pagata). Una scheda collegata a un documento fiscale già emesso risponde 409 conflict.
dalla revisione 2026-10-06

Nuovo endpoint.

Risposte
200
Il documento con la riga aggiunta e i totali ricalcolati.
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
Non applicabile (motivo in `error.reason`) oppure scheda bloccata.
500
Errore imprevisto del server. Il dettaglio finisce nei log, non nella risposta.
Richiesta
curl -X POST https://api.officina.it/v1/worksheets/{id}/waste-disposal \
  -H "Authorization: Bearer ofk_live_LA_TUA_CHIAVE" \
  -H "X-API-Version: 2026-10-31"