# Product write-off

> Create a write-off, fill it with items and post it so that stock actually decreases.

Task: write off products from a shop’s warehouse — defects, loss, shortage — and see the stock decrease.

A write-off in BILLZ is a two-step process: first the document is assembled, then it is posted. **Only posting moves stock.**

## Steps

```plaintext
GET  /v2/write-off-reason        write-off reason (reference data)
POST /v2/write-off               ──> document ID (draft)
POST /v2/write-off/:id/add       each item in a separate request
PUT  /v2/write-off/finish/:id    post ──> stock decreases
```

All modifying methods are asynchronous. The `Billz-Response-Channel: HTTP` header is required, otherwise only the event identifier is returned instead of the result.

### 1. Write-off reason

```bash
curl -X GET 'https://api-admin.billz.ai/v2/write-off-reason' \
  -H 'Authorization: Bearer TOKEN'
```

```json
{ "count": 5, "write_off_reasons": [ { "id": "d6ccea76-...", "name": "Defect" } ] }
```

Reasons are created only in the BILLZ interface.

### 2. Create the document

```bash
curl -X POST 'https://api-admin.billz.ai/v2/write-off' \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Billz-Response-Channel: HTTP' \
  -d '{
    "name": "Write-off 2026-08-22",
    "reason_id": "d6ccea76-7412-48b0-bad3-e0bc0f41673f",
    "shop_id": "70919136-9481-4c7e-8581-685d750d67a9",
    "comment": ""
  }'
```

The write-off shop is set by the `shop_id` field.

> **Call the method only with `Billz-Response-Channel: HTTP`**
>
> If `shop_id` is not accessible to the token, the document is not created, and the “no access to the shop” refusal is visible only in the response channel. Without the header, `200` and a UUID are returned.

### 3. Add items

One item per request. `:id` is the document ID from the previous step.

```bash
curl -X POST 'https://api-admin.billz.ai/v2/write-off/WRITE_OFF_ID/add' \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Billz-Response-Channel: HTTP' \
  -d '{
    "shop_id": "70919136-9481-4c7e-8581-685d750d67a9",
    "product_id": "aba9d9ad-5d37-4836-81a4-9a60648d087e",
    "writeoff_measurement_value": 1
  }'
```

| Field                        | What it is                                      |
| ---------------------------- | ----------------------------------------------- |
| `shop_id`                    | the write-off shop, the same as in the document |
| `product_id`                 | product UUID from `GET /v2/products`            |
| `writeoff_measurement_value` | quantity to write off                           |

> **An item cannot be removed with an integration key**
>
> If an extra item got into the draft, the document is cancelled (`PUT /v2/write-off/cancel/:id`) and assembled again.

### 4. Post

```bash
curl -X PUT 'https://api-admin.billz.ai/v2/write-off/finish/WRITE_OFF_ID' \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -H 'Billz-Response-Channel: HTTP'
```

Posting and the stock write-off (FIFO) run **in a single transaction**.

> **Stock changes immediately; the catalog and reports show it with a delay**
>
> A successful response to `finish` means the stock has been changed and applies to new operations. In the catalog and reports the change appears with a small delay.

To cancel an unposted document — `PUT /v2/write-off/cancel/:id`.

## Permissions

For a web-interface user, write-off is split into **four independent permissions**:

| Permission                | What it opens                                                    |
| ------------------------- | ---------------------------------------------------------------- |
| View write-off list       | list of write-offs, items, exports                               |
| View write-off cost price | the document card with cost price                                |
| Create write-off          | creation, `/add`, `/remove`, editing and cancellation (`cancel`) |
| Complete write-offs       | `PUT /v2/write-off/finish/:id`                                   |

The write-off report is a separate permission (“Write-offs” report).

## How to check the result

| What                  | Method                                                                    |
| --------------------- | ------------------------------------------------------------------------- |
| Write-off report      | `GET /v1/write-off-report-table`                                          |
| Current product stock | `GET /v2/products` → `shop_measurement_values[].active_measurement_value` |

## Related processes

Transfer and purchase order follow the same “assemble → fill → post” scheme — see [warehouse processes](/en/concepts/processes/).