---
title: "Apply the waste-disposal charge"
method: POST
path: "/v1/worksheets/{id}/waste-disposal"
tags: ["Worksheets"]
---

# Apply the waste-disposal charge

`POST /v1/worksheets/{id}/waste-disposal`

## Request

- Base URL: `https://api.officina.it`
- URL: `https://api.officina.it/v1/worksheets/{id}/waste-disposal`
- Auth: HTTP bearer

Appends the charge line — quantity 1 at the previewed amount, unit
`lav`, the company's default VAT rate (its first enabled one), last
position — recomputes the totals and returns the updated document
(as the line-items batch does).

The rules are re-checked server-side and the line is written in one
transaction holding the document's row lock, so concurrent calls run
one after the other and add the line once. When the charge can't be
applied the response is `409 waste_disposal_not_applicable` with
`error.reason` (`disabled`, `already_applied`, `nothing_to_charge`, and
on worksheets `fully_paid`). A worksheet behind an issued fiscal document answers `409 conflict`.

## Response `200`

Line added. Returns the updated document (with `line_items`).

- Worksheet: A workshop work order. Belongs to one customer and (usually) one vehicle. Lifecycle: draft → waiting → started → completed → delivered → archived. Each state has a matching nullable `*_at` timestamp populated by the server when the transition fires. Totals are server-computed from the embedded line items and rounded to the working currency precision. They are read-only on the wire. `line_items` is populated on detail / write responses and omitted (or `null`) on list responses to keep page payloads small.
  - `object` 'worksheet', required
  - `id` string, required
  - `seq_number` integer, required: Per-company human-friendly sequence number. Allocated server-side at creation; never reused.
  - `status` 'draft' | 'waiting' | 'started' | 'completed' | 'delivered' | 'archived', required
  - `title` string, nullable
  - `comments` string, nullable
  - `internal_comments` string, nullable: Workshop-internal notes; surfaced through the mobile app for the workshop's own users (no customer-facing channel exposes this field).
  - `customer_id` string, required
  - `vehicle_id` string, nullable
  - `assigned_to` string, nullable
  - `work_category_id` string, nullable
  - `km` number, nullable: Odometer reading captured when the worksheet was opened. Free-form decimal because some workshops record fuel mileage or hour-meter values in the same field.
  - `created_by` string, required
  - `created_by_full_name` string: Display string of the user who created the worksheet — denormalized for list rendering without a join.
  - `customer_name` string
  - `vehicle_name` string, nullable
  - `vehicle_license` string, nullable
  - `work_category_name` string, nullable
  - `work_category_ids` string[], required: Every work category ("categoria") of the document, in the order chosen. `work_category_id` (kept for clients that handle a single category) always equals the first. `[]` when the document has none, never null. Available since revision 2026-10-03.
  - `work_categories` WorkCategory[], required: The same list as `work_category_ids` with each category's name, same order. `work_category_name` is the first one's name. Available since revision 2026-10-03.
    - `object` 'work_category', required
    - `id` string, uuid, required
    - `name` string, required
  - `total_before_tax` number
  - `total_tax` number
  - `total_after_tax` number
  - `total_after_discount` number
  - `total_discount` number
  - `total_price` number
  - `total_payments` number
  - `outstanding_payments` number
  - `fiscal_document_type` string: Which fiscal document the worksheet produces: "fattura" (default) or "scontrino".
  - `invoice_id` string, nullable: Detail responses only — the first linked invoice, when one exists. Drives the Vedi Fattura action.
  - `receipt_id` string, nullable: Detail responses only — the linked scontrino for scontrino-type worksheets, when one exists.
  - `linked_invoices` WorksheetFiscalDocument[]: Detail responses only — compact rows for the Fattura tab (fattura-type worksheets).
    - `object` 'worksheet_fiscal_document', required
    - `id` string, required
    - `seq_number` integer, required
    - `issued_at` string, date-time, nullable, required
    - `created_at` string, date-time, required
    - `total_after_discount` number, double, required
    - `outstanding_payments` number, double, required
  - `linked_receipt` WorksheetFiscalDocument: One compact linked fiscal document on a worksheet detail — seq_number 0 means a draft ("Non emessa" / "Bozza").
    - `object` 'worksheet_fiscal_document', required
    - `id` string, required
    - `seq_number` integer, required
    - `issued_at` string, date-time, nullable, required
    - `created_at` string, date-time, required
    - `total_after_discount` number, double, required
    - `outstanding_payments` number, double, required
  - `frozen` boolean: Detail responses only (since 2026-07-19) — true when a linked invoice has a non-draft electronic invoice; mutations are rejected with 409 and the app hides/blocks Modifica.
  - `total_work_cost` number: Internal labour cost ex-VAT (Costi di lavorazione): the value typed by hand when `work_cost_manual` is true, otherwise the sum of the lines' `unit_cost × quantity` for unit types h, gg, lav, min. Correct on every revision and on list responses since 2026-10-15 (lists used to return 0).
  - `total_article_cost` number: Internal parts cost ex-VAT: the value typed by hand when `article_cost_manual` is true, otherwise the sum of the other lines' `unit_cost × quantity`.
  - `work_cost_manual` boolean: True when `total_work_cost` was typed by hand; line changes no longer move it. Reset with `PATCH` `total_work_cost: null`.
  - `article_cost_manual` boolean: True when `total_article_cost` was typed by hand.
  - `waiting_at` string, date-time, nullable
  - `started_at` string, date-time, nullable
  - `completed_at` string, date-time, nullable
  - `delivered_at` string, date-time, nullable
  - `archived_at` string, date-time, nullable
  - `created_at` string, date-time, required
  - `updated_at` string, date-time, required
  - `deleted_at` string, date-time, nullable: Soft-deletion timestamp. Populated on the response from DELETE /v1/worksheets/{id}. Worksheets with a non-null deleted_at are not returned by list/detail endpoints.
  - `line_items` WorkLineItem[], nullable: Embedded line items. Populated on detail / create / patch / delete / transition responses. List responses set this to `null` to keep the payload small.
    - `object` 'work_line_item', required
    - `id` string, required
    - `line_type` 'item' | 'note' | 'separator', required: `item` is a priced line. `note` is a description-only line and `separator` an empty spacer row: both print without quantity, price and VAT and carry zero amounts (ignore their numeric fields). Lines from documents without types report `item`.
    - `article_id` string, nullable: Optional link to a catalog article. When set, edits flow through the article inventory bookkeeping.
    - `description` string, required
    - `quantity` number, required
    - `unit_type` string, required
    - `unit_price` number, required
    - `unit_discount_rate` number
    - `tax_rate` number, required
    - `vat_code` string, nullable
    - `total_price` number, required
    - `unit_cost` number, nullable: Internal cost per unit, ex-VAT, never printed on documents. Fixed when the line was written: the article's purchase price at that moment, or the `unit_cost` sent. `null` when unknown.
    - `total_before_tax` number
    - `total_tax` number
    - `total_after_tax` number
    - `position` integer, required
    - `created_at` string, date-time, required
  - `documents` WorksheetDocument[], nullable: Attachments (Documenti Allegati). Populated on the same responses as `line_items`; null on lists.
    - `object` 'worksheet_document', required
    - `id` string, required
    - `name` string, required
    - `content_type` string, required
    - `description` string, nullable
    - `url` string, required
    - `file_size_bytes` integer, required
    - `created_at` string, date-time, required

## Other responses

- `401`: Missing, malformed, expired, or wrong-audience bearer token.
- `402`: The company has no active subscription, or its plan does not include API access. API access is included in the Business and Illimitato plans.
- `403`: The authenticated user lacks the required permission.
- `404`: Resource does not exist OR belongs to a different company. The two cases are intentionally indistinguishable.
- `409`: `waste_disposal_not_applicable` (`error.reason` says why) or `conflict` (the worksheet is frozen).
- `500`: Unhandled server error. Detail is logged, not exposed.

---

[API](https://skmtc.dev/officina/apis/officina-it-api.md) · [All operations](https://skmtc.dev/officina/apis/officina-it-api/llms.txt) · [OpenAPI document](https://skmtc.dev/officina/apis/officina-it-api/revisions/7da3fccfe551?raw)
