APIv3
Exit Documentation

Sold Items Report

Retrieve the Sold Items Report by date range, location, customer account, inventory category, and salesperson.

Sold Items Report

GET/api/v3/reports/sold-items

Required scope: reports:read

Requires live report and invoice-list permissions and an accessible account. The authenticated credential determines the SalesBinder account; customer_id means the customer account shown in the report's Account filter. There is no tenant-selection parameter.

Users without all-invoice visibility are restricted to their own invoices, even if another salesperson is requested. Effective filters are returned. Without unit-cost permission, net_cost and profit are omitted from every row and summary, and sorting by either is rejected.

Query parameters

ParameterDefaultDescription
date_fromToday minus 30 daysInclusive invoice issue date in YYYY-MM-DD format. Supply both dates or omit both.
date_toTodayInclusive invoice issue date, on or after date_from. Must be before date_from plus one year.
location_idAll locationsAccount-owned location UUID. Matches the item's current location or the linked variation-location record, as in the web report; this is not an invoice-location or historical shipping-location filter.
customer_idAll visible customersAccount-owned customer UUID.
category_idAll categoriesInventory category UUID, including its subcategories as in the web report.
user_idAll permitted salespeopleInvoice salesperson UUID; forced to the caller when all-invoice visibility is unavailable.
group_byitemitem, account, or variation.
sorttotal_qtyitem_name, item_number, customer_name, total_qty, net_revenue, net_cost, profit, or last_sold_date. Customer sorting requires account grouping; cost/profit sorting requires unit-cost permission.
directiondescasc or desc.
page1Page number, normalized to at least 1.
limit20Grouped rows per page, clamped to 1–100.
include_totaltrueInclude exact grouped-row counts. Accepts true, false, 1, or 0.
include_summarytrueInclude totals and the top-ten category revenue breakdown for the full filtered report. Accepts the same boolean values.

Dates use the application calendar with years 1000–9999. A full calendar year, including a leap year, is supported (for example January 1–December 31). Invalid or oversized ranges, unsupported options, malformed UUIDs, and unavailable filter targets return 422 invalid_query_parameter with the offending param. Unknown and other-account filter targets receive the same error.

bash
curl 'https://yourbusiness.salesbinder.com/api/v3/reports/sold-items?date_from=2026-10-01&date_to=2026-10-31&group_by=variation&limit=100' \
  --header 'Authorization: Bearer YOUR_API_KEY'

Grouping

  • item: one row per inventory item.
  • account: one row per item/customer combination, not a single combined row per customer. Customer IDs remain available for deleted customers, while their names can be null.
  • variation: one row per item variation, combining surviving variations across locations. Historical attributes are preferred over live values. Orphaned variation-location records and unlinked historical snapshots retain distinct groups rather than merging into ordinary items.

Every row has an opaque id for its grouping identity. It is stable across pagination and filtering while the underlying identity is unchanged. Changing grouping mode or deleting/reassigning a variation association can change the group identity. Sorting uses item ID and the applicable customer/variation identity as tie-breakers.

Response

Returns the standard paginated list envelope with object, url, has_more, data, and pagination, plus effective filters, currency, and currency_decimal_places.

Row fieldDescription
id, objectOpaque group ID and sold_items_group.
item_id, item_number, item_name, skuInventory identity and current item metadata.
category_id, category_nameCurrent item category.
last_sold_dateLatest matching invoice issue date.
total_qtySigned quantity as a decimal string, preserving fractional quantities.
net_revenueSales revenue after discounts, excluding tax.
net_cost, profitCost and revenue minus cost; omitted without unit-cost permission.
customer_id, customer_namePresent only with account grouping.
variation_id, variation_location_idPresent only with variation grouping. Nullable; location ID is returned only when the group uses exactly one non-null variation-location ID.
variation_attributesVariation grouping only: an array of {name, value} strings; empty for groups without readable attributes.

Money values are decimal strings at the account's report precision (0–4). Quantity strings use up to four decimal places without trailing zeroes. Discounted lines, including fully discounted sales, and signed quantities follow the web report calculations. Services and lines without a surviving inventory item are excluded; cancelled invoices are excluded. No currency conversion occurs.

Summary

When include_summary=true, the response includes:

json
{
  "summary": {
    "totals": {
      "total_qty": "3.25",
      "net_revenue": "32.50",
      "net_cost": "13.00",
      "profit": "19.50"
    },
    "top_categories": [],
    "category_limit": 10
  }
}

Totals cover the entire filtered result, not just the current page. top_categories contains up to ten positive-revenue categories, ordered by revenue, with category_id, category_name, net_revenue, and numeric percentage. Percentages use the full signed report revenue as the denominator; they need not sum to 100 and may exceed 100 when other categories have negative revenue. When total revenue is nonpositive, the breakdown is empty. It is not a complete category listing.

Pagination counts refer to grouped rows, not invoice lines or quantity sold. include_total=false omits total_records and total_pages; include_summary=false omits summary. Both options independently skip their corresponding queries. Empty reports return an empty data array and zero totals when requested.

For larger exports, fetch the summary only on the first page. Results can change between requests, and large page offsets still have a cost. Responses use Cache-Control: no-store.