Distru Sales Order Item History API
The SalesOrderItemHistory API from Distru — 1 operation(s) for salesorderitemhistory.
The SalesOrderItemHistory API from Distru — 1 operation(s) for salesorderitemhistory.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/distru:distru-salesorderitemhistory-api"
curl "https://apis.io/api/v1/apis?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
license:
name: Proprietary
url: https://www.distru.com/legal/terms-of-service
title: Distru Sales Order Item History API
version: '1.0'
servers:
- url: https://app.distru.com
security:
- Bearer: []
tags:
- name: SalesOrderItemHistory
paths:
/public/v1/reports/sales-order-item-history:
get:
description: '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.'
operationId: DistruPublic.V1.Report.SalesOrderItemHistoryController.index
parameters:
- description: Keep only line items whose order is in one of the given statuses. Repeat the key to pass several; multiple values are OR'd (an order matches if its status is any of them). SCREAMING_CASE enum. Omit to include every status.
in: query
name: status
required: false
style: form
explode: false
schema:
type: array
items:
enum:
- PENDING
- PROCESSING
- READY_TO_SHIP
- DELIVERING
- DELIVERED
- COMPLETED
- CANCELED
type: string
- description: Keep only line items whose order has one of the given invoice payment statuses. Repeat the key for several values (OR'd). SCREAMING_CASE enum. Omit to include every payment status.
in: query
name: payment_status
required: false
style: form
explode: false
schema:
type: array
items:
enum:
- NOT_PAID
- PARTIALLY_PAID
- FULLY_PAID
- OVER_PAID
type: string
- description: 'Keep only line items whose order was created through one of the given sources. Repeat the key for several values (OR''d). SCREAMING_CASE enum: LEAFLINK, EXTERNAL_BUYER, INTERNAL_USER, API. Omit to include every source.'
in: query
name: order_source
required: false
style: form
explode: false
schema:
type: array
items:
enum:
- LEAFLINK
- EXTERNAL_BUYER
- INTERNAL_USER
- API
type: string
- description: Filter line items by whether they are samples. ONLY returns only sample line items; EXCLUDE drops all sample line items. Omit to include both sample and non-sample items.
in: query
name: sample
required: false
example: ONLY
schema:
type: string
enum:
- ONLY
- EXCLUDE
- description: Filter line items by whether their package is a Metrc trade sample. ONLY returns only trade-sample-package items; EXCLUDE drops them. Omit to include both. Meaningful only for companies on Metrc — the trade-sample-package column exists only there.
in: query
name: trade_sample_packages
required: false
example: EXCLUDE
schema:
type: string
enum:
- ONLY
- EXCLUDE
- description: Filter by order date, as a comma-separated ISO8601 range `start,end` interpreted in the company's timezone. Either side may be left blank for an open-ended range (`2026-01-01T00:00:00Z,` = on or after that instant; `,2026-02-01T00:00:00Z` = up to it). When this param is omitted entirely the report falls back to the last 30 days by order date; this default applies to `order_datetime` only.
in: query
name: order_datetime
required: false
example: 2026-01-01T00:00:00Z,2026-02-01T00:00:00Z
schema:
type: string
- description: Filter by the order's delivery date, as a comma-separated ISO8601 range `start,end` (company timezone). Either side may be blank for an open-ended range. Omit to leave delivery date unfiltered — unlike `order_datetime`, this filter has no 30-day default.
in: query
name: delivery_datetime
required: false
example: 2026-01-01T00:00:00Z,2026-02-01T00:00:00Z
schema:
type: string
- description: Filter by the order's due date, as a comma-separated ISO8601 range `start,end` (company timezone). Either side may be blank for an open-ended range. Omit to leave due date unfiltered.
in: query
name: due_datetime
required: false
example: 2026-01-01T00:00:00Z,2026-02-01T00:00:00Z
schema:
type: string
- description: Filter by when the order was created, as a comma-separated ISO8601 range `start,end` (company timezone). Either side may be blank for an open-ended range. Omit to leave creation date unfiltered.
in: query
name: created_datetime
required: false
example: 2026-01-01T00:00:00Z,2026-02-01T00:00:00Z
schema:
type: string
- description: Filter by when the order was last modified, as a comma-separated ISO8601 range `start,end` (company timezone). Either side may be blank for an open-ended range. Omit to leave last-modified date unfiltered.
in: query
name: updated_datetime
required: false
example: 2026-01-01T00:00:00Z,2026-02-01T00:00:00Z
schema:
type: string
- description: Keep only line items whose order total falls within a comma-separated `min,max` range. Either side may be left blank for an open-ended bound (`100,` = 100 or more; `,500` = 500 or less). Bounds are inclusive order totals in the company's currency.
in: query
name: total
required: false
example: 100,500
schema:
type: string
- description: When `true`, keep only orders matched to a compliance transfer (Metrc or BioTrack); when `false`, keep only orders not matched to one. Omit to include both.
in: query
name: matched_with_compliance_transfer
required: false
example: true
schema:
type: boolean
- description: Free-text search across order number, customer name, and LeafLink short ID; matches line items whose order matches on any of the three (substring, case-insensitive). Omit to skip text search.
in: query
name: search
required: false
example: SO-1001
schema:
type: string
- description: Keep only line items whose customer is one of the given customers, by Distru customer (company relationship) ID. Repeat the key for several (OR'd). IDs are the id strings returned elsewhere in the API.
in: query
name: company_relationship_ids
required: false
style: form
explode: false
schema:
type: array
items:
type: string
- description: Keep only line items whose customer belongs to one of the given customer groups, by group ID. Repeat the key for several (OR'd).
in: query
name: company_relationship_group_ids
required: false
style: form
explode: false
schema:
type: array
items:
type: string
- description: Keep only line items whose order ships from one of the given licenses, by license ID. Repeat the key for several (OR'd).
in: query
name: shipped_from_license_ids
required: false
style: form
explode: false
schema:
type: array
items:
type: string
- description: Keep only line items whose order was placed against one of the given menus, by menu ID. Repeat the key for several (OR'd).
in: query
name: menu_ids
required: false
style: form
explode: false
schema:
type: array
items:
type: string
- description: Keep only line items whose product belongs to one of the given brands, by brand ID. Repeat the key for several (OR'd).
in: query
name: brand_ids
required: false
style: form
explode: false
schema:
type: array
items:
type: string
- description: Keep only line items whose order owner (the assigned user) is one of the given users, by user ID. Repeat the key for several (OR'd).
in: query
name: owner_ids
required: false
style: form
explode: false
schema:
type: array
items:
type: string
- description: Keep only line items whose order was created by one of the given users, by user ID. Repeat the key for several (OR'd).
in: query
name: creator_ids
required: false
style: form
explode: false
schema:
type: array
items:
type: string
- description: Keep only line items sourced from one of the given batches, by batch ID. Repeat the key for several (OR'd).
in: query
name: batch_ids
required: false
style: form
explode: false
schema:
type: array
items:
type: string
- description: Keep only line items for one of the given products, by product ID. Repeat the key for several (OR'd).
in: query
name: product_ids
required: false
style: form
explode: false
schema:
type: array
items:
type: string
- description: Keep only line items whose product belongs to one of the given product groups, by product group ID. Repeat the key for several (OR'd).
in: query
name: product_group_ids
required: false
style: form
explode: false
schema:
type: array
items:
type: string
responses:
'200':
description: The Sales Order Item History report
content:
'*/*':
schema:
$ref: '#/components/schemas/SalesOrderItemHistoryReport'
'400':
description: Invalid parameters
content:
'*/*':
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Missing or invalid API token
content:
'*/*':
schema:
$ref: '#/components/schemas/ErrorResponse'
'403':
description: The API token lacks the required permission
content:
'*/*':
schema:
$ref: '#/components/schemas/ErrorResponse'
summary: Get the Sales Order Item History report
tags:
- SalesOrderItemHistory
components:
schemas:
SalesOrderItemHistoryReportRow:
description: 'A single row of the Sales Order Item History report (one sales order line item). The properties below are the columns every company receives. Companies on a compliance integration receive extra keys that are not declared above — their exact set, and the manifest column''s key name, vary by company, so read `meta.columns` for the authoritative list. Those compliance keys are: `package_label`, `package_batch_number`, `package_expiration_date`, `package_harvest_date`, the potency keys `thc`, `thc_mg_g`, `thc_mg_ml`, `total_thc`, `total_thc_mg_g`, `total_thc_mg_ml`, `cbd`, `cbd_mg_g`, `cbd_mg_ml`, `total_cbd`, `total_cbd_mg_g`, `total_cbd_mg_ml` (the percentage keys and the `mg_*` keys are all decimal strings), `shipped_from_license`, and a manifest-number key named for the active compliance system (`metrc_manifest_number` or `biotrack_manifest_number`). Any Order custom fields configured for the company are also appended, keyed by the slugified field label. Every compliance and custom-field key is null when it has no value for a row, so null-check any key outside the declared set.
'
properties:
batch_id:
description: 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.
type: string
batch_number:
description: The batch number the line item was sourced from, or `null` if not batch-sourced.
type: string
brand:
description: The product's brand name, or `null` if the product has no brand.
type: string
brand_id:
description: The brand's ID, or `null` if the product has no brand.
type: string
category:
description: The product's category.
type: string
customer:
description: The order's customer name, or `null` if the order has no customer.
type: string
customer_id:
description: The customer's ID, or `null` if the order has no customer.
type: string
default_unit_cost:
description: 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.
type: string
default_unit_price:
description: The product's default unit price as a string.
type: string
default_wholesale_price:
description: The product's default wholesale price as a string, or `null` if unset.
type: string
delivery_date:
description: The order's delivery date in the company's timezone, or `null` if the order has no delivery date.
type: string
delivery_date_utc:
description: The same delivery date in UTC, or `null` if the order has no delivery date.
type: string
due_date:
description: The order's due date in the company's timezone, or `null` if the order has no due date.
type: string
due_date_utc:
description: The same due date in UTC, or `null` if the order has no due date.
type: string
group:
description: The product's group, or `null` if the product is in no group.
type: string
invoice_numbers:
description: Comma-separated invoice numbers linked to this line item's order, sorted for a stable order; `null` if the order has no invoices.
type: string
line_item_id:
description: The line item's ID.
type: string
order_date:
description: The order date, formatted in the company's timezone.
type: string
order_date_utc:
description: The same order date, formatted in UTC.
type: string
order_id:
description: The ID of the order this line item belongs to.
type: string
order_item_price:
description: The line item's unit price as a string.
type: string
order_number:
description: 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.
type: string
package_id:
description: 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.
type: string
price_base:
description: The line item's unit price before its price tier applied, as a string. Same as the order item's `price_base`.
type: string
price_tier_id:
description: 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.
type: string
price_tier_mode:
description: '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).'
enum:
- AUTO
- OVERRIDE
- NONE
type: string
price_tier_name:
description: The tier's name when it priced the line item, or `null` when no tier did.
type: string
price_tier_percent:
description: The tier's percent as a string (e.g. "12.5") for PERCENT_OFF, else `null`.
type: string
price_tier_price:
description: The tier's amount as a string for AMOUNT_OFF and FLAT_PRICE, else `null`.
type: string
price_tier_pricing_type:
description: '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.'
enum:
- PERCENT_OFF
- AMOUNT_OFF
- FLAT_PRICE
type: string
price_tier_version_id:
description: 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.
type: string
price_tier_version_is_live:
description: '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.'
type: boolean
product:
description: The product's name. Inactive products carry a prefix on the name.
type: string
product_id:
description: The product's ID.
type: string
product_sku:
description: The product's SKU, or an empty string if none is set.
type: string
quantity:
description: The line item's ordered quantity as a string.
type: string
returned_quantity:
description: The quantity returned on this line item as a string; 0 when nothing was returned.
type: string
sales_order_owner_id:
description: The order owner's ID — the `id` [GET /public/v1/users](#get-users) returns — or `null` if unassigned.
type: string
sales_rep:
description: The order owner's name, treated as the sales rep; `null` if unassigned.
type: string
source_package:
description: 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.
type: string
status:
description: The order's status as a SCREAMING_CASE token.
enum:
- PENDING
- PROCESSING
- READY_TO_SHIP
- DELIVERING
- DELIVERED
- COMPLETED
- CANCELED
type: string
subcategory:
description: The product's subcategory, or `null` if none.
type: string
upc:
description: The product's UPC, or `null` if none is set.
type: string
vendor:
description: The product's vendor name.
type: string
vendor_id:
description: The vendor's ID.
type: string
required:
- category
- quantity
- price_tier_mode
- price_base
- order_item_price
- vendor_id
- vendor
- default_unit_price
- product_id
- product
- status
- order_number
- order_date_utc
- order_date
- order_id
- line_item_id
title: SalesOrderItemHistoryReportRow
type: object
ErrorResponse:
description: The envelope returned by every failed request (400, 401, 403, 404, 429). `errors` always holds at least one entry.
properties:
errors:
description: One or more errors describing why the request failed.
items:
$ref: '#/components/schemas/Error'
type: array
required:
- errors
title: ErrorResponse
type: object
SalesOrderItemHistoryReport:
description: The Sales Order Item History report
properties:
data:
description: The report rows, one per matching sales order line item; empty when nothing matches the filters.
items:
$ref: '#/components/schemas/SalesOrderItemHistoryReportRow'
type: array
meta:
$ref: '#/components/schemas/SalesOrderItemHistoryReportMeta'
required:
- meta
- data
title: SalesOrderItemHistoryReport
type: object
SalesOrderItemHistoryReportMeta:
description: Report-level metadata
properties:
columns:
description: The ordered column definitions for this response, including any compliance-only and custom-field columns. Use these keys to read the data rows.
items:
$ref: '#/components/schemas/SalesOrderItemHistoryReportColumn'
type: array
date_range:
description: 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.
type: string
report:
description: The report identifier, always `sales_order_item_history`.
type: string
required:
- columns
- date_range
- report
title: SalesOrderItemHistoryReportMeta
type: object
Error:
description: A single error describing one problem with the request.
properties:
message:
description: Human-readable, customer-facing description of what went wrong.
type: string
pointer:
description: 'Path to the offending field in the request: field names and, for items in a list, their integer position — e.g. ["items", 0, "quantity"]. ["base"] means the error applies to the request as a whole rather than one field.'
items: {}
type: array
required:
- message
- pointer
title: Error
type: object
SalesOrderItemHistoryReportColumn:
description: 'One column definition for the report. Iterate `meta.columns` to discover the exact set of keys present in each data row for this company (the set varies with the company''s compliance integration and configured Order custom fields).
'
properties:
key:
description: The key this column appears under in every data row (e.g. `order_number`).
type: string
label:
description: The human-readable column heading (e.g. `Order Number`).
type: string
required:
- label
- key
title: SalesOrderItemHistoryReportColumn
type: object
securitySchemes:
Bearer:
type: http
scheme: bearer
description: 'API token generated in Distru (Settings → Distru API). Send it on every request as `Authorization: Bearer YOUR_API_TOKEN`.'