# Delete a line item

```http
DELETE https://secure.yoprint.com/v2/api/store/{team_slug}/v2/sales_order/order_item/{order_item_unique_key}
```

- API version: v2
- Operation ID: `v2_public_order_item_destroy`
- Section: Sales › [Sales order line items](https://developer.yoprint.com/reference/sales-order-line-items.md)
- Web page: https://developer.yoprint.com/reference/sales-order-line-items/v2-order-item-destroy/
- Authentication: `Authorization: Bearer YOUR_API_KEY`

Deletes one line and recalculates the order's totals.

`{order_item_unique_key}` is the line's `id` (a hash id) from the order's line items. Its `orditm_` unique key is also accepted, but no API answer shows it, so use `id`.

Deleting a line that is already deleted is safe: it returns 200 with the line and `action_performed: "NONE"` (a line an integration brought in is refused with 422 even then). Otherwise the answer is the deleted line in `data.item` (`trashed: true`) with `action_performed: "DELETED"`.

## Permission

Needs permission to edit this sales order or quote:

- The team owner
- A role with `update_all_order`
- A role with `update_self_order`, when the order was created by or is assigned to the API key's user
- The person who created a draft, with `create_order`

Quotes use the same sales order permissions.

## Business rules

- Lines an integration brought in can't be deleted through the API: "Cannot delete external object from API."
- Refused while the line's job has a decoration setup that needs repair.

## Side effects

- Removes the line from the order's shipments and from every invoice of the order, and cancels its stock reservations and purchase links.
- Recalculates the job's decoration pricing, the order totals and auto-managed invoices.
- On a published sales order with QuickBooks Online connected, queues the order's QuickBooks sync.
- Refreshes the order for people who have it open in the web app. No email is sent.

## Path parameters

- `team_slug` (string, required): Your team slug, shown as Team ID next to your API key in Profile. Example `your-team`.
- `order_item_unique_key` (string, required): The line's `id` (a hash id), from the order's line items. Its `orditm_…` unique key is also accepted, but no API answer shows it, so use `id`. Example `Owr88lhAk28aqL`.

## Request body

This operation takes no request body.

### Example request

```bash
curl -X DELETE 'https://secure.yoprint.com/v2/api/store/your-team/v2/sales_order/order_item/Owr88lhAk28aqL' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Accept: application/json' \
  -H 'X-Yoprint-Decimal-Format: exact-v1'
```

## Response

`200` Successful response.

Fields:

- `data` (object, required)
  - `object_type` (string, optional): Always `"order_item"`.
  - `action_performed` (string, optional): `NONE` when nothing changed. One of: `"CREATED"`, `"UPDATED"`, `"DELETED"`, `"NONE"`.
  - `has_changes` (boolean, optional)
  - `item` (object, optional): One line. It has the request's groups (`product`, `pricing`, `quantity`, `job`, `weight`, `position`) as saved, with the prices YoPrint worked out, and the same values again in `_meta`. A few groups differ from the request: the catalog cost comes back as `pricing.catalog.cost` with its date as a date-time, and a linked `job` also has its `unique_key` and `scoped_id` (`JOB-1001`). Each group's `_meta.editable_fields_on_update` lists the request paths an update accepts for that group (`pricing.type` is listed, but it must stay the line's own).
    - `_meta` (object, optional): The line's own values again (`id`, `type`, `order_id`, `unit_price`, `subtotal` and so on). Always an object.
    - `id` (string, optional)
    - `inventory_status` (string | null, optional): Stock status of the line.
    - `job` (object, optional)
    - `lock_version` (integer | null, optional): The line's own lock version (a microsecond timestamp).
    - `order_id` (string, optional)
    - `order_unique_key` (string, optional): The order's `unique_key`. The line's own `unique_key` is not in the answer: use `id`.
    - `position` (integer, optional)
    - `pricing` (object, optional)
    - `pricing_rule_applied` (object | null, optional): The pricing rule that set the line's product price, or null when no rule did. List the line items, Get one line item and the bulk save answer with the full summary below. Other answers carry only `type`, the two ids and the two totals.
      - `after` (string, optional): Full summary only: the price after the rule, as a decimal string.
      - `after_total` (decimal pair, optional): The product price per unit after the rule. 6 decimal places. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
      - `base` (string, optional): Full summary only: that starting price, as a decimal string with at least 2 decimal places.
      - `base_type` (string, optional): Full summary only: what the rule started from: the supplier price for catalog lines, the product's own price for other lines. One of: `"supplier_price"`, `"base_price"`.
      - `normal_price` (string | null, optional): Full summary only: what the line would cost with no rule. For catalog lines the supplier price plus the group's catalog markup as it is now; otherwise the same as `base`.
      - `original_total` (decimal pair, optional): The product price per unit before the rule. 6 decimal places. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
      - `pricing_group_id` (string | null, optional): The pricing group whose rule applied.
      - `pricing_group_name` (string | null, optional): Full summary only: the group's name now.
      - `pricing_group_removed` (boolean | null, optional): Full summary only: true when the group was removed since. The line keeps its price.
      - `pricing_rule_id` (string | null, optional): The rule that applied.
      - `rule` (object | null, optional): Full summary only: the rule as the group holds it now, with its current name and position (1 is the first rule checked). Null when the rule no longer exists.
        - `id` (string, optional)
        - `label` (string | null, optional)
        - `position` (integer, optional)
      - `type` (string, optional): `product` on a line.
    - `product` (object, optional)
    - `quantity` (object, optional): The quantity, trailing zeros dropped: 10 is `{ "value": 10, "dp": 0 }`.
    - `subtotal` (decimal pair, optional): `unit_price` times the quantity. 4 decimal places: 125.00 is `{ "value": 1250000, "dp": 4 }`. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
    - `trashed` (boolean, optional): true when the line was deleted.
    - `type` (string, optional): The kind of line: db_catalog, user_simple, db_variant, custom or fee.
    - `unit_price` (decimal pair, optional): The price of one unit: the product price plus the decoration price. 6 decimal places: 12.50 is `{ "value": 12500000, "dp": 6 }`. A decimal pair: the amount is `value` ÷ 10^`dp` (`{ "value": 1250, "dp": 2 }` is 12.50). Read `dp` every time: it can differ between fields and records. See https://developer.yoprint.com/concepts/money-and-quantities.md.
  - `lock_version` (object, optional): The order's lock versions after this call. Each is a whole number (a microsecond timestamp) that changes on every save, or null.
    - `order` (object, required)
      - `invoice_lock_version` (integer | null, optional)
      - `job_lock_version` (integer | null, optional)
      - `order_item_lock_version` (integer | null, optional)
      - `order_lock_version` (integer | null, optional): The order's own `lock_version`.
      - `payment_lock_version` (integer | null, optional)
      - `shipment_lock_version` (integer | null, optional)
- `status` (integer, required)
- `success` (boolean, required)

Example response:

```json
{
  "data": {
    "action_performed": "DELETED",
    "has_changes": true,
    "item": {
      "id": "Owr88lhAk28aqL",
      "job": {
        "id": "K6iF8n29iwOZnj",
        "scoped_id": "JOB-1001",
        "type": "linked",
        "unique_key": "job_EXAMPLEuniqueKey"
      },
      "lock_version": 1793696400234567,
      "order_id": "V4keXwwxMQyXw7",
      "order_unique_key": "ord_EXAMPLEuniqueKey",
      "position": 200000,
      "pricing": {
        "product": {
          "override": true,
          "total": {
            "dp": 6,
            "value": 12500000
          }
        },
        "type": "product_cost_service"
      },
      "product": {
        "properties": {
          "customer_supplied": false,
          "id": "nqSB3HG1O2u5Jg"
        },
        "type": "user_simple"
      },
      "quantity": {
        "total": {
          "dp": 0,
          "value": 10
        },
        "type": "unit"
      },
      "subtotal": {
        "dp": 4,
        "value": 1250000
      },
      "trashed": true,
      "type": "user_simple",
      "unit_price": {
        "dp": 6,
        "value": 12500000
      }
    },
    "lock_version": {
      "order": {
        "invoice_lock_version": 1793696400123456,
        "job_lock_version": 1793696400123456,
        "order_item_lock_version": 1793696400234567,
        "order_lock_version": 1793696400234567,
        "payment_lock_version": 1793696400123456,
        "shipment_lock_version": null
      }
    },
    "object_type": "order_item"
  },
  "status": 200,
  "success": true
}
```

## Errors

- `401` The API key is missing or wrong (`unauthenticated`).
- `403` You are not allowed to do this. `api_access_not_in_plan`: your team's plan doesn't include API access (Pro and above, with an active subscription or trial), so every request answers this until the team upgrades. When your role lacks the permission the operation needs, the body is only `{"message": "Insufficient Permission"}`. Other refusals use the error envelope, with `unauthorized` or `user_is_not_authorized`.
  - When: The API key's role can't edit this order. Fix: Ask the team owner for sales order edit permission.
- `404` Not found. `page_not_found`: the team slug is unknown, you are not a member of the team, or an id in the path is not one of this team's. `code: null`, with a message that starts "No query results for": there is no record with that id.
  - When: The line does not exist in this team. Fix: Check the id.
- `422` The request was refused and changed nothing. `validation_failed` lists what to fix in `error.fields`; other codes name a business rule, explained in `error.message`. A few checks answer with only `{"message": "..."}`. An operation that calls another service (a payment provider, a carrier, an accounting app) can answer `connect_timeout` ("Please retry again") when that service does not answer in time: the change may or may not have happened there, so read the record back before you retry.
  - When: The line came from an integration, or its job's services need repair. Fix: Change it where it came from, or repair the job in the web app.

## Related

- [Add, change and delete line items in one save](https://developer.yoprint.com/reference/sales-order-line-items/v2-order-item-bulk.md): `POST /v2/api/store/{team_slug}/v2/sales_order/{order_unique_key}/order_item/bulk`
- [List the line items of a sales order or quote](https://developer.yoprint.com/reference/sales-order-line-items/v2-order-item-index.md): `GET /v2/api/store/{team_slug}/v2/sales_order/{order_unique_key}/order_item`
