---
title: "Removes a line from a sales order (the app's line remove button)."
method: DELETE
path: "/api/v1/sales-orders/{id}/lines/{lineId}"
tags: ["SalesOrders"]
---

# Removes a line from a sales order (the app's line remove button).

`DELETE /api/v1/sales-orders/{id}/lines/{lineId}`

## Request

- Base URL: `https://app.flexonthejob.com`
- URL: `https://app.flexonthejob.com/api/v1/sales-orders/{id}/lines/{lineId}`
- Auth: HTTP bearer

Requires `ManageSalesOrders` and an `Idempotency-Key` header; no body. Only a
line that is on no live transfer can go — not even a completed one ("Cannot delete: item
is part of a transfer. Cancel the transfer first."); use `/returns` for delivered
goods. The line is soft-deleted (it disappears from `lines`), totals, payment status
and draft invoices are recomputed and the history records "Removed item '…'
(via API key '…')".

## Path parameters

- `id` integer, required
- `lineId` integer, required

## Response `200`

Removed; body is the order with its remaining lines.

- SalesOrderDetailDto: One sales order with its lines, as returned by `GET /api/v1/sales-orders/{id}` and `POST /api/v1/sales-orders`.
  - `id` integer: Numeric id used in `/api/v1/sales-orders/{id}`. Unique within this organization. Example: `318`.
  - `syncId` string, uuid: Stable cross-device identifier (GUID) — also the pagination cursor value. Example: `7b1e2c3d-4f5a-4b6c-9d8e-0f1a2b3c4d5e`.
  - `orderNumber` string: Order number assigned by the app, `SO` + two-digit year + two-digit month + a four-digit sequence per month. Example: `SO26090007`.
  - `status` string: Order status. One of `Pending` (created, lines can be added, fulfilment not started or not covering every line), `Picking` (a pick transfer covers every line and items are being picked), `Packed` (everything picked), `Shipped` (every transfer has shipping info), `Delivered` (every transfer completed), `Complete` (terminal: marked complete, or delivered and fully invoiced and paid) and `Cancelled` (terminal). Legacy rows may still say the deprecated `Confirmed`. Over the API `/fulfill` starts fulfilment and the later statuses follow from `/pick`, `/complete-pick`, `/ship` and `/deliver`, as in the app.
  - `paymentStatus` string, nullable: Payment status: `Pending`, `Partial`, `Paid`, `Overdue`, `Refunded`, `Invoiced` or `Cancelled`. Example: `Pending`. Null on some legacy rows.
  - `fulfillmentStatus` string, nullable: Aggregate status of the order's transfers (the earliest one wins): `None` (no transfer yet), `Draft`, `Pending`, `InTransit`, `AtWaypoint`, `InTransitToWaypoint`, `InTransitToDestination`, `Completed`, `Cancelled`, `Failed`. Example: `Pending`.
  - `customerId` integer: Customer id (see `/api/v1/customers/{id}`). Example: `42`.
  - `customerName` string, nullable: Customer name at read time. Example: `Acme Plumbing`.
  - `customerPONumber` string, nullable: The customer's own purchase-order reference; null when none. Example: `PO-7781`.
  - `orderDate` string, date-time: Order date as entered in the app: the organization's local calendar date with no UTC offset (not an instant; do not convert it between time zones). Example: `2026-09-23T00:00:00`.
  - `requestedDeliveryDate` string, date-time, nullable: Requested delivery date, same organization-local calendar-date format as `orderDate`; null when none. Example: `2026-09-30T00:00:00`.
  - `subTotal` number, double: Sum of the line totals, in the organization's currency. Example: `1250.00`.
  - `taxRate` number, double: Tax rate in percent (8.25 = 8.25 %). 0 for a tax-exempt customer. Example: `8.25`.
  - `taxAmount` number, double: Tax, `subTotal` × `taxRate` / 100, in the organization's currency. Example: `103.13`.
  - `shippingCost` number, double: Shipping charged on the order, in the organization's currency. Example: `25.00`.
  - `totalAmount` number, double: Order total, `subTotal` + `taxAmount` + `shippingCost`, in the organization's currency. Example: `1378.13`.
  - `amountPaid` number, double: Amount paid so far, in the organization's currency. Example: `500.00`.
  - `balanceDue` number, double: Still owed: `totalAmount` − `amountPaid` − store credit applied, in the organization's currency. Example: `878.13`.
  - `lineCount` integer: Number of lines on the order (removed lines excluded). Example: `3`.
  - `createdAt` string, date-time: Creation time, ISO-8601 UTC. Example: `2026-09-23T14:05:00Z`.
  - `updatedAt` string, date-time, nullable: Last recorded modification (header or line edits, lines added or removed, status change, fulfilment and pick progress, `fulfillmentStatus` change), ISO-8601 UTC; null when never modified since creation. Payments do not move it (`paymentStatus` / `amountPaid` / `balanceDue` can change without it). Example: `2026-09-23T15:12:00Z`.
  - `deliveryAddressId` integer, nullable: Id of the customer address the order is delivered to; null when none. Example: `77`.
  - `paymentTerms` string, nullable: Payment terms text. Example: `Net 30`. Null when none.
  - `notes` string, nullable: Free-text notes on the order. Example: `Leave at loading dock.` Null when none.
  - `lines` SalesOrderLineDto[]: The order lines (removed lines excluded), in the order they were added.
    - `id` integer: Line id. Example: `1502`.
    - `itemId` integer, nullable: Catalog item id as used by `/api/v1/items/{id}`; null for a legacy free-text line.
    - `description` string: Line description (the item name when the line was added). Example: `Copper 12/2 Romex`.
    - `quantityOrdered` number, double: Quantity ordered. Example: `10`.
    - `quantityPicked` number, double: Quantity picked (scanned) so far. Example: `4`.
    - `quantityShipped` number, double: Quantity shipped so far. Example: `0`.
    - `unitPrice` number, double: Unit price, in the organization's currency. Example: `125.00`.
    - `unitCost` number, double: Unit cost, in the organization's currency; 0 when unknown. Example: `80.00`.
    - `lineTotal` number, double: Line total, `quantityOrdered` × `unitPrice`, in the organization's currency. Example: `1250.00`.
    - `notes` string, nullable: Line notes. Example: `Cut to 25 ft lengths`. Null when none.

## Other responses

- `400`: Missing `Idempotency-Key`.
- `401`: Unauthorized
- `403`: Forbidden
- `404`: No such sales order in this organization, or the line is not one of its live lines (already removed).
- `409`: The line is on a transfer, the order is `Complete` or `Cancelled`, or the key's creator is unknown on this server.
- `429`: Too Many Requests

---

[API](https://skmtc.dev/flexonthejob/apis/flex-api.md) · [All operations](https://skmtc.dev/flexonthejob/apis/flex-api/llms.txt) · [OpenAPI document](https://skmtc.dev/flexonthejob/apis/flex-api/revisions/19c8f4d27acf?raw)
