---
title: "Get the Sales Order Item History report"
method: GET
path: "/public/v1/reports/sales-order-item-history"
tags: ["SalesOrderItemHistory"]
---

# Get the Sales Order Item History report

`GET /public/v1/reports/sales-order-item-history`

## Request

- Base URL: `https://app.distru.com`
- URL: `https://app.distru.com/public/v1/reports/sales-order-item-history`
- Auth: HTTP bearer

Returns one row per sales order line item, joining each item to its order, product, brand, vendor, and customer. Each row carries the order's dates and status, the product identity (name, SKU, UPC, category, default costs/prices), and the line item's own quantity, returned quantity, and price. This is a read-only reporting endpoint; it never changes orders, inventory, or compliance state.

Scoping and date default:
• Rows are always scoped to the API key's company and to the orders the key's user is permitted to see.
• When `order_datetime` is omitted the report covers the last 30 days by order date, evaluated in the company's timezone. This 30-day default applies only to `order_datetime` — the other date filters (`delivery_datetime`, `due_datetime`, `created_datetime`, `updated_datetime`) add no default and simply go unfiltered when omitted.
• The resolved date range (human-readable) and the exact column set are returned under `meta`, so read `meta.columns` to discover which columns a given company's response actually contains before indexing into rows by key.

Column set varies by company:
• Companies on a compliance integration (Metrc or BioTrack) additionally get package columns (label, batch number, expiration/harvest date), potency columns (THC/CBD % and mg per g/mL), the compliance manifest number, and the shipped-from license. Companies with no compliance integration do not receive these columns at all.
• The trade-sample-package column is Metrc-only.
• Any Order custom fields configured for the company are appended as extra columns keyed by the field's label.

Value formatting (rows mirror the CSV export):
• Dates come as display-formatted strings, each in two variants — one in the company's timezone (e.g. `order_date`) and one in UTC (e.g. `order_date_utc`).
• Money and quantity cells are returned as strings (the currency/percent formatting of the CSV is stripped, e.g. `"1234.56"`) so they match the rest of the API. Identifier-like cells whose number has a significant leading zero (e.g. an order number `"0042"`) keep their display string so the zero is not lost.
• `status` and other enum-bearing cells are returned as SCREAMING_CASE tokens (matching the rest of the public API), not the internal human-readable labels.
• An empty cell is returned as an empty string or null depending on the column; treat any non-core column as possibly blank.
• Each row also carries `sales_order_owner_id` (after `sales_rep`) and `batch_id` and `package_id` (after `batch_number`), so a row can be followed to the user, batch or package endpoints without a lookup. The CSV export leaves these ID columns out.
• Each row also carries the line's price before its price tier (`price_base`) and the tier that priced it (the `price_tier_*` columns, after `order_item_price`), so a tier's discount on a line is `price_base` minus `order_item_price`, times `quantity`. The tier columns hold the tier as it was when it priced the line, so deleted tiers still show. The CSV export leaves these columns out too.

Ordering and result size:
• Rows come back newest-first by order date (descending). The endpoint exposes no sort or pagination controls, so a matching filter returns every line item in one response — there is no `next_page` cursor. Narrow the date range or other filters to bound the result size of a large history.

Required permission: `reports_permissions_sales_order_item_history` — the same permission that gates the Sales Order Item History report in the app.

## Query parameters

- `status` string[]
- `payment_status` string[]
- `order_source` string[]
- `sample` 'ONLY' | 'EXCLUDE'
- `trade_sample_packages` 'ONLY' | 'EXCLUDE'
- `order_datetime` string
- `delivery_datetime` string
- `due_datetime` string
- `created_datetime` string
- `updated_datetime` string
- `total` string
- `matched_with_compliance_transfer` boolean
- `search` string
- `company_relationship_ids` string[]
- `company_relationship_group_ids` string[]
- `shipped_from_license_ids` string[]
- `menu_ids` string[]
- `brand_ids` string[]
- `owner_ids` string[]
- `creator_ids` string[]
- `batch_ids` string[]
- `product_ids` string[]
- `product_group_ids` string[]

## Response `200`

The Sales Order Item History report

- SalesOrderItemHistoryReport: The Sales Order Item History report
  - `data` SalesOrderItemHistoryReportRow[], required: The report rows, one per matching sales order line item; empty when nothing matches the filters.
    - `batch_id` string: The ID of the batch the line item was picked from — the `id` [GET /public/v1/batches](#get-batches) returns — or `null` if it has none.
    - `batch_number` string: The batch number the line item was sourced from, or `null` if not batch-sourced.
    - `brand` string: The product's brand name, or `null` if the product has no brand.
    - `brand_id` string: The brand's ID, or `null` if the product has no brand.
    - `category` string, required: The product's category.
    - `customer` string: The order's customer name, or `null` if the order has no customer.
    - `customer_id` string: The customer's ID, or `null` if the order has no customer.
    - `default_unit_cost` string: The product's default unit cost as a string, or `null` if unset. This is the product default, not the line item's negotiated cost.
    - `default_unit_price` string, required: The product's default unit price as a string.
    - `default_wholesale_price` string: The product's default wholesale price as a string, or `null` if unset.
    - `delivery_date` string: The order's delivery date in the company's timezone, or `null` if the order has no delivery date.
    - `delivery_date_utc` string: The same delivery date in UTC, or `null` if the order has no delivery date.
    - `due_date` string: The order's due date in the company's timezone, or `null` if the order has no due date.
    - `due_date_utc` string: The same due date in UTC, or `null` if the order has no due date.
    - `group` string: The product's group, or `null` if the product is in no group.
    - `invoice_numbers` string: Comma-separated invoice numbers linked to this line item's order, sorted for a stable order; `null` if the order has no invoices.
    - `line_item_id` string, required: The line item's ID.
    - `order_date` string, required: The order date, formatted in the company's timezone.
    - `order_date_utc` string, required: The same order date, formatted in UTC.
    - `order_id` string, required: The ID of the order this line item belongs to.
    - `order_item_price` string, required: The line item's unit price as a string.
    - `order_number` string, required: The order's human-readable order number. Always returned as a string; one with a significant leading zero (e.g. `"0042"`) is preserved as-is so the zero isn't lost.
    - `package_id` string: The ID of the package the line item was picked from — the `id` [GET /public/v1/packages](#get-packages) returns — or `null` if it has none.
    - `price_base` string, required: The line item's unit price before its price tier applied, as a string. Same as the order item's `price_base`.
    - `price_tier_id` string: The ID of the [price tier](#model-pricetier) that priced the line item, or `null` when none did. The tier may have been deleted since.
    - `price_tier_mode` 'AUTO' | 'OVERRIDE' | 'NONE', required: How the line item takes a price tier, as the order item's `price_tier_mode`: AUTO, OVERRIDE (locked to the tier in `price_tier_version_id`) or NONE (no tier).
    - `price_tier_name` string: The tier's name when it priced the line item, or `null` when no tier did.
    - `price_tier_percent` string: The tier's percent as a string (e.g. "12.5") for PERCENT_OFF, else `null`.
    - `price_tier_price` string: The tier's amount as a string for AMOUNT_OFF and FLAT_PRICE, else `null`.
    - `price_tier_pricing_type` 'PERCENT_OFF' | 'AMOUNT_OFF' | 'FLAT_PRICE': How the tier set the price: PERCENT_OFF (`price_base` minus `price_tier_percent`% of it), AMOUNT_OFF (`price_base` minus `price_tier_price`) or FLAT_PRICE (`price_tier_price` replaces it). `null` when no tier priced the line item.
    - `price_tier_version_id` string: The ID of the tier snapshot that priced the line item, as the order item's `price_tier_version.id`, or `null` when no tier did.
    - `price_tier_version_is_live` boolean: As the order item's `price_tier_version.is_live`: false when the tier was edited or deleted since it priced the line item; `null` when no tier did.
    - `product` string, required: The product's name. Inactive products carry a prefix on the name.
    - `product_id` string, required: The product's ID.
    - `product_sku` string: The product's SKU, or an empty string if none is set.
    - `quantity` string, required: The line item's ordered quantity as a string.
    - `returned_quantity` string: The quantity returned on this line item as a string; 0 when nothing was returned.
    - `sales_order_owner_id` string: The order owner's ID — the `id` [GET /public/v1/users](#get-users) returns — or `null` if unassigned.
    - `sales_rep` string: The order owner's name, treated as the sales rep; `null` if unassigned.
    - `source_package` string: The compliance label of the source package this line item's package was repackaged from, or `null` when it was not repackaged from another package.
    - `status` 'PENDING' | 'PROCESSING' | 'READY_TO_SHIP' | 'DELIVERING' | 'DELIVERED' | 'COMPLETED' | 'CANCELED', required: The order's status as a SCREAMING_CASE token.
    - `subcategory` string: The product's subcategory, or `null` if none.
    - `upc` string: The product's UPC, or `null` if none is set.
    - `vendor` string, required: The product's vendor name.
    - `vendor_id` string, required: The vendor's ID.
  - `meta` SalesOrderItemHistoryReportMeta, required: Report-level metadata
    - `columns` SalesOrderItemHistoryReportColumn[], required: The ordered column definitions for this response, including any compliance-only and custom-field columns. Use these keys to read the data rows.
      - `key` string, required: The key this column appears under in every data row (e.g. `order_number`).
      - `label` string, required: The human-readable column heading (e.g. `Order Number`).
    - `date_range` string, required: The human-readable order-date range the report actually covers, reflecting the `order_datetime` filter or the last-30-days default when it was omitted.
    - `report` string, required: The report identifier, always `sales_order_item_history`.

## Other responses

- `400`: Invalid parameters
- `401`: Missing or invalid API token
- `403`: The API token lacks the required permission, or team restrictions hide the record

## Changes

- **2026-10-10** `86808c1d09ea`: 9 info
  - added the optional property `data/items/price_tier_id` to the response with the `200` status
  - added the optional property `data/items/price_tier_name` to the response with the `200` status
  - added the optional property `data/items/price_tier_percent` to the response with the `200` status
  - added the optional property `data/items/price_tier_price` to the response with the `200` status
  - …5 more
- **2026-10-07** `e8639f7dafed`: 3 info
  - added the optional property `data/items/batch_id` to the response with the `200` status
  - added the optional property `data/items/package_id` to the response with the `200` status
  - added the optional property `data/items/sales_order_owner_id` to the response with the `200` status

[Operation history](https://skmtc.dev/distru/apis/distru-api/changes/public/v1/reports/sales-order-item-history/get.md)

---

[API](https://skmtc.dev/distru/apis/distru-api.md) - [All operations](https://skmtc.dev/distru/apis/distru-api/llms.txt) - [OpenAPI document](https://skmtc.dev/distru/apis/distru-api/revisions/9d851a88e82f?raw)
