Home Integration API reference

Integration API reference

REST API for integrations and external apps

Data & Analytics

All report endpoints below use GET with integration API authentication under /api/v1/integration/reports/*. Unless noted otherwise, format=csv streams a UTF-8 BOM download, pagination is ignored for CSV exports, a non-empty q must be at least 2 characters, and any supplied location_id must belong to the business; unknown ids return 404 and out-of-scope ids return 403.

Profit & loss (report)

Returns profit and loss figures for a resolved date range using the same calculation pipeline as the web report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/profit-loss
Permissionprofit_loss_report.view.
Default rangeThe current financial year when start_date and end_date are omitted.
Breakdown filterq filters total_sell_by_subtype, module rows, and gross_profit_label, but it does not change the headline numeric totals.
CSV behaviorformat=csv downloads section/field/value rows for the resolved range.
Success response200 with the full profit/loss payload.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_idintegerNoOptional business-location filter.
user_idintegerNoOptional business user filter. Invalid ids return 422.
qstringNoFilters subtype/module breakdowns by label or numeric id-like values without changing the summary totals.

ProfitLossBreakdownRow object

FieldTypeDescription
sub_typestring | nullSell subtype label or null for normal sells.
total_before_taxnumberSubtotal before tax for that subtype.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.user_id, data.qmixedEchoes the resolved filters.
Headline totals such as opening_stock, closing_stock, total_purchase, total_sell, total_expense, gross_profit, and net_profitnumberMain profit/loss figures from TransactionUtil::getProfitLossDetails().
data.total_sell_by_subtypearray<ProfitLossBreakdownRow>Sales grouped by subtype.
data.left_side_module_data, data.right_side_module_dataarray<object>Optional module hook rows with label/value pairs.
data.gross_profit_labelarray<string>Localized gross-profit explanation strings.

Status codes

StatusWhen it happensResponse shape
200The report was generated successfully.{ "data": { ... } } or CSV download.
403The token user lacks profit_loss_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, q is too short, or user_id is invalid.Laravel validation JSON or { "message": string }.
500The backend profit/loss calculation threw an exception.{ "message": "Could not compute profit and loss" }

Purchase & sale (report)

Returns the same purchase-versus-sale summary cards used by the web Purchase & Sale report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/purchase-sell
Permissionpurchase_n_sell_report.view.
Default rangeThe current calendar month when dates are omitted.
q behaviorThe query is validated and echoed as data.q, but it does not change any totals.
CSV behaviorformat=csv downloads flattened section/field/value rows.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_idintegerNoOptional location filter.
qstringNoEcho-only search term.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.qmixedEchoes the resolved filters.
data.purchaseobjectPurchase totals: inclusive/exclusive tax, due amount, shipping, and additional expense.
data.sellobjectSell totals: inclusive/exclusive tax, invoice due, shipping, and additional expense.
data.total_purchase_return_inc_tax, data.total_sell_return_inc_taxnumberInclusive-tax return totals.
data.difference.total, data.difference.duenumberThe same summary formulas shown in the web report.

Status codes

StatusWhen it happensResponse shape
200The summary was returned successfully.{ "data": { ... } } or CSV download.
403The token user lacks purchase_n_sell_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, or q is too short.Laravel validation JSON or { "message": string }.

Tax (report)

Returns input, output, expense, and module output tax totals using the same summary logic as the web Tax report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/tax-report
Permissiontax_report.view.
Default rangeThe current calendar month when dates are omitted.
Module output taxAdditional module tax comes from ModuleUtil::getModuleData('getModuleOutputTax').
q behaviorFilters by_tax_rate rows and recomputes section totals and totals.tax_difference; module output tax is left unchanged.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_idintegerNoOptional location filter.
contact_idintegerNoOptional contact filter. Invalid ids return 422.
qstringNoMatches tax names, numeric tax ids, and grouped sub-tax names/ids.

TaxBreakdownRow object

FieldTypeDescription
tax_id, tax_nameinteger | stringThe matched tax rate identity.
tax_amountnumberAmount attributed to the rate or grouped tax.
is_tax_groupbooleanWhether the row represents a grouped tax.
group_tax_detailsarray<object> | nullSub-tax breakdown when is_tax_group is true.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.contact_id, data.qmixedEchoes the resolved filters.
data.input_tax, data.output_tax, data.expense_taxobjectEach section contains total_tax and by_tax_rate.
data.module_output_taxobjectContains by_module and total.
data.totalsobjectContains total_output_tax_including_modules and tax_difference.

Status codes

StatusWhen it happensResponse shape
200The tax report was returned successfully.{ "data": { ... } } or CSV download.
403The token user lacks tax_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, contact_id is invalid, or q is too short.Laravel validation JSON or { "message": string }.
500The tax helper pipeline threw an exception.{ "message": "Could not compute tax report" }

Supplier & customer (report)

Lists supplier/customer balance-style rows using the same aggregates and due formula as the web Supplier & Customer report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/customer-supplier
Permissioncontacts_report.view.
Date behaviorWhen both dates are omitted, the report runs across all transaction dates.
Text filtersSupports q or legacy search. The resolved text value is returned as data.search and meta.q.
Row scopeThe underlying query joins transactions, so only contacts with at least one matching transaction appear.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together when either is used.
location_id, contact_id, customer_group_idintegerNoOptional location/contact/group filters. Invalid contact or group ids return 422.
contact_typestringNocustomer or supplier. The controller also includes contacts with type both.
q, searchstringNoMatches contact name, supplier business name, or numeric contact id.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.

CustomerSupplierReportRow object

FieldTypeDescription
id, name, name_only, supplier_business_name, contact_typemixedContact identity and display fields.
total_purchase, total_purchase_return, total_invoice, total_sell_returnnumberPurchase/sell movement totals.
purchase_paid, invoice_received, sell_return_paid, purchase_return_receivednumberPayment totals.
opening_balance, opening_balance_paid, opening_balance_duenumberOpening-balance figures.
total_ledger_discount_sell, total_ledger_discount_purchase, duenumberLedger-discount totals and the final computed due amount.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.contact_id, data.customer_group_id, data.contact_type, data.searchmixedEchoes the applied filters.
data.contactsarray<CustomerSupplierReportRow>The current page of matching contacts.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata and the resolved text filter.

Status codes

StatusWhen it happensResponse shape
200The report rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks contacts_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, q is too short, or a contact/group filter is invalid.Laravel validation JSON or { "message": string }.

Customer groups (report)

Aggregates final sell totals by customer group using the same query as the web Customer Groups report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/customer-group
Permissioncontacts_report.view.
Date behaviorWhen both dates are omitted, the report runs across all final sells.
Ungrouped salesSales with no customer group still appear as one row with customer_group_id = null.
CSV behaviorDownloads customer_group_id, name, and total_sell.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together when either is used.
location_idintegerNoOptional location filter.
customer_group_idintegerNoOptional single-group filter. Invalid ids return 422.
qstringNoMatches group name text or an exact numeric customer_group_id.

CustomerGroupReportRow object

FieldTypeDescription
customer_group_idinteger | nullGroup id or null for ungrouped sales.
namestring | nullGroup name when the group exists.
total_sellnumberFinal sell total for the group.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.customer_group_id, data.qmixedEchoes the applied filters.
data.groupsarray<CustomerGroupReportRow>All matching group aggregates.

Status codes

StatusWhen it happensResponse shape
200The grouped totals were returned successfully.{ "data": { ... } } or CSV download.
403The token user lacks contacts_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, q is too short, or customer_group_id is invalid.Laravel validation JSON or { "message": string }.

Stock on hand (report)

Lists quantity-on-hand rows by variation and location using the same stock query as the web Stock report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/stock-on-hand
Permissionstock_report.view.
Data sourceProductUtil::getProductStockDetails().
Manufacturing columntotal_mfg_stock only appears when Manufacturing is installed and the subscription/user permissions allow it.
Price visibilityunit_price needs access_default_selling_price; stock_price and potential_profit need view_purchase_price.

Query parameters

ParameterTypeRequiredDescription
location_idintegerNoOptional location filter.
category_id, sub_category_id, brand_id, unit_id, product_id, repair_model_idintegerNoOptional business-scoped filters. Invalid ids fail validation.
tax_idintegerNoOptional tax-rate filter.
type, active_statestringNotype accepts single or variable. active_state accepts active or inactive.
only_mfg_products, not_for_sellingbooleanNoOptional boolean filters.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches product, SKU, variation, location, or numeric product/variation ids.

StockOnHandReportRow object

FieldTypeDescription
product_id, variation_id, location_id, location_namemixedProduct/variation/location identity.
product, sku, variation, type, unit, category_namemixedMain descriptive fields.
enable_stock, stock, alert_quantitymixedStock status and alert figures. stock is null when stock tracking is disabled.
total_sold, total_transfered, total_adjustednumberMovement totals for the row.
unit_price, stock_price, stock_value_by_sale_price, potential_profitnumber | nullPrice/value fields gated by selling-price or purchase-price permissions.
total_mfg_stocknumber | nullManufacturing-only stock figure when enabled.
product_custom_field1 ... product_custom_field4string | nullConfigured custom product fields.

Top-level JSON response

FieldTypeDescription
data.location_idinteger | nullEchoes the optional location filter.
data.filtersobjectEchoes all other filters, including include_manufacturing and q.
data.itemsarray<StockOnHandReportRow>The current page of stock rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata and the resolved search term.

Status codes

StatusWhen it happensResponse shape
200The stock rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks stock_report.view.{ "message": "Unauthorized" }
422A filter failed validation or q is too short.Laravel validation JSON or { "message": string }.
500The stock query failed unexpectedly.{ "message": "Could not load stock report" }

Stock expiry (report)

Lists purchase-line stock that still has remaining quantity, with expiry-date and lot details matching the web Stock Expiry report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/stock-expiry
Permissionstock_report.view.
Row scopeOnly purchase lines with stock left greater than zero are returned.
Date filterexp_date_filter restricts rows to exp_date <= filter.
CSV behaviorFilenames are stock-expiry-all.csv or stock-expiry-until-{date}.csv.

Query parameters

ParameterTypeRequiredDescription
location_idintegerNoOptional location filter.
category_id, sub_category_id, brand_id, unit_idintegerNoOptional business-scoped product filters.
exp_date_filterstringNoBusiness-format date normalized before comparison.
only_mfg_productsbooleanNoRestricts rows to production-purchase stock only.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches product, SKU, variation, location, lot, purchase ref, or numeric ids.

StockExpiryReportRow object

FieldTypeDescription
product, product_display, sku, product_type, variation, sub_sku, product_variationmixedProduct identity fields.
location, location_idmixedLocation details.
mfg_date, exp_date, is_expiredmixedManufacturing/expiry dates and the computed expiry flag.
unit, stock_leftmixedRemaining quantity and unit.
ref_no, transaction_id, purchase_line_id, lot_numbermixedSource purchase and lot identifiers.

Top-level JSON response

FieldTypeDescription
data.location_id, data.exp_date_filter, data.only_mfg_products, data.qmixedEchoes the resolved filters.
data.itemsarray<StockExpiryReportRow>The current page of expiry rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The expiry rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks stock_report.view.{ "message": "Unauthorized" }
422A filter failed validation or q is too short.Laravel validation JSON or { "message": string }.
500The expiry query failed unexpectedly.{ "message": "Could not load stock expiry report" }

Lot report

Returns remaining stock by lot/batch using the same stock math as the web Lot report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/lot-report
Permissionstock_report.view.
Row scopeOnly purchase lines with a non-null lot_number are included.
Inventory mathstock, total_sold, and total_adjusted follow the same correlated purchase-allocation logic as the web report.
CSV behaviorformat=csv downloads lot-report-all.csv.

Query parameters

ParameterTypeRequiredDescription
location_idintegerNoOptional location filter.
category_id, sub_category_id, brand_id, unit_idintegerNoOptional business-scoped product filters.
only_mfg_productsbooleanNoRestricts rows to production-purchase stock only.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches product, SKU, variation, lot number, or numeric product/variation ids.

LotReportRow object

FieldTypeDescription
product, product_display, variation_name, sub_sku, product_typemixedProduct and variation identifiers.
lot_number, exp_date, is_expiredmixedLot and expiry metadata.
stock, total_sold, total_adjusted, unitmixedRemaining quantity and movement totals.

Top-level JSON response

FieldTypeDescription
data.location_id, data.only_mfg_products, data.qmixedEchoes the resolved filters.
data.itemsarray<LotReportRow>The current page of lot rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The lot rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks stock_report.view.{ "message": "Unauthorized" }
422A filter failed validation or q is too short.Laravel validation JSON or { "message": string }.
500The lot report query failed unexpectedly.{ "message": "Could not load lot report" }

Stock adjustment (report)

Combines the stock-adjustment summary totals with a paginated adjustment list, matching the current web report split.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/stock-adjustment-report
Primary permissionstock_report.view.
Secondary row permissionList rows only render when the token user has stock_adjustment.view, stock_adjustment.create, or view_own_stock_adjustment.
Summary behaviordata.summary is returned even when list rows are omitted. When the user only has view_own_stock_adjustment, the row query is user-scoped but the summary remains aggregate.
Price visibilityfinal_total and total_amount_recovered are null without view_purchase_price.
CSV behaviorExports only adjustment rows, never the summary. If rows are not visible, the CSV contains headers only.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_idintegerNoOptional location filter.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches reference numbers, location names, product fields, or numeric adjustment/line ids.

StockAdjustmentReportSummary object

FieldTypeDescription
total_amount, total_recovered, total_normal, total_abnormalnumberSummary totals from the stock adjustment report cards.

StockAdjustmentReportRow object

FieldTypeDescription
id, transaction_date, ref_nomixedAdjustment identity fields.
location_name, added_bystring | nullDisplay fields for the location and creator.
adjustment_type, adjustment_type_labelmixedStored adjustment type and its translated label.
final_total, total_amount_recoverednumber | nullCost/recovered amounts, hidden when purchase-price visibility is not allowed.
additional_notesstring | nullSaved notes for the adjustment.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.qmixedEchoes the resolved filters.
data.summaryStockAdjustmentReportSummaryAggregate stock-adjustment totals.
data.itemsarray<StockAdjustmentReportRow>Visible list rows. May be empty when the user lacks secondary list permissions.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.q, meta.items_includedmixedPagination metadata plus a flag showing whether row data was included.

Status codes

StatusWhen it happensResponse shape
200The report summary was returned successfully, with rows included when allowed.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks stock_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, or q is too short.Laravel validation JSON or { "message": string }.
500The summary query or row query failed unexpectedly.{ "message": string }

Returns the top-selling products by units sold using the same logic as the web Trending Products report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/trending-products
Permissiontrending_product_report.view.
Data sourceProductUtil::getTrendingProducts().
Date behaviorWhen dates are omitted, no date filter is applied. When limit is omitted, the util defaults to the top 5 products.
Success response200 with one summary object containing the returned items and total_units_sold.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_idintegerNoOptional location filter.
category_id, sub_category_id, brand_id, unit_idintegerNoOptional business-scoped product filters.
product_typestringNosingle, variable, or combo.
limitintegerNoMaximum rows to return, from 1 to 100.
qstringNoMatches product name, SKU, unit short name, or a numeric product id.

TrendingProductsReportRow object

FieldTypeDescription
product, sku, unitmixedProduct identity fields.
total_unit_soldnumberTotal units sold for the product, net of returns.
labelstringPrebuilt chart/display label in the form name - sku (unit).

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.category_id, data.sub_category_id, data.brand_id, data.unit_id, data.product_type, data.limit, data.qmixedEchoes the applied filters.
data.total_units_soldnumberSum of total_unit_sold across the returned items.
data.itemsarray<TrendingProductsReportRow>The returned trending product rows.

Status codes

StatusWhen it happensResponse shape
200The report was returned successfully.{ "data": { ... } } or CSV download.
403The token user lacks trending_product_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The trending-products query failed unexpectedly.{ "message": "Could not load trending products" }

Items report

Returns purchase-to-sell or purchase-to-stock-adjustment mapping rows using the same source query as the web Items report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/items-report
Permissionpurchase_n_sell_report.view.
Source querytransaction_sell_lines_purchase_lines joined to purchase lines, sell lines, and stock adjustment lines.
Date behaviorpurchase_start/purchase_end and sale_start/sale_end are independent pairs. The sale range matches either the sell date or the stock adjustment date.
Price visibilitypurchase_price, selling_unit_price, and subtotal are null without view_purchase_price.

Query parameters

ParameterTypeRequiredDescription
purchase_start, purchase_endstringConditionalBusiness-format purchase-date range. Both must be sent together and purchase_start must not be after purchase_end.
sale_start, sale_endstringConditionalBusiness-format sale/adjustment date range. Both must be sent together and sale_start must not be after sale_end.
supplier_id, customer_id, location_idintegerNoOptional supplier, customer, and location filters.
only_mfg_productsbooleanNoRestricts rows to production_purchase rows.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches product fields, contacts, refs, invoice numbers, location, lot, sell line note, or numeric ids.

ItemsReportRow object

FieldTypeDescription
sku, product_name, product_display, product_type, sell_line_notemixedProduct and line-description fields.
purchase_date, purchase_ref_no, purchase_type, purchase_id, is_opening_stock_purchase, lot_numbermixedPurchase-side fields.
supplier, supplier_business_name, supplier_displaymixedSupplier fields.
purchase_pricenumber | nullPurchase price per unit when purchase-price access is allowed.
sell_date, sale_invoice_no, stock_adjustment_ref_no, is_stock_adjustmentmixedSell-side or stock-adjustment-side linkage fields.
customer, customer_business_name, customer_display, locationmixedCustomer and location fields.
quantity, qty_returned, unit, selling_unit_price, subtotalmixedMovement and amount fields, with pricing gated by view_purchase_price.

Top-level JSON response

FieldTypeDescription
data.purchase_start, data.purchase_end, data.sale_start, data.sale_end, data.supplier_id, data.customer_id, data.location_id, data.only_mfg_products, data.qmixedEchoes the resolved filters.
data.itemsarray<ItemsReportRow>The current page of mapping rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The report rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks purchase_n_sell_report.view.{ "message": "Unauthorized" }
422A date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The items-report query failed unexpectedly.{ "message": "Could not load items report" }

Product purchase report

Lists grouped purchase-line rows using the same query as the web Product Purchase report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/product-purchase-report
Permissionpurchase_n_sell_report.view.
Date behaviorWhen dates are omitted, the report runs across all purchase transactions.
Variation lookupvariation_id must belong to a product in the business; otherwise the endpoint returns 404.
Price visibilityunit_purchase_price and subtotal are null without view_purchase_price.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
variation_id, location_id, supplier_id, brand_idintegerNoOptional variation, location, supplier, and brand filters.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches product fields, supplier fields, purchase ref, or numeric transaction/purchase-line ids.

ProductPurchaseReportRow object

FieldTypeDescription
purchase_line_id, transaction_id, ref_no, transaction_datemixedPurchase-line and transaction identity fields.
product_name, product_display, product_type, sub_skumixedProduct identity fields.
supplier, supplier_business_name, supplier_displaymixedSupplier fields.
purchase_qty, quantity_adjusted, unitmixedQuantity and unit fields.
unit_purchase_price, subtotalnumber | nullAmount fields gated by view_purchase_price.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.variation_id, data.location_id, data.supplier_id, data.brand_id, data.qmixedEchoes the applied filters.
data.itemsarray<ProductPurchaseReportRow>The current page of grouped purchase-line rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The report rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks purchase_n_sell_report.view.{ "message": "Unauthorized" }
404variation_id does not belong to a product in the business.{ "message": "Variation not found" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The product-purchase query failed unexpectedly.{ "message": "Could not load product purchase report" }

Product sell report

Returns final sell-line rows using the same detailed query as the web Product Sell report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/product-sell-report
Permissionpurchase_n_sell_report.view.
Row scopeOnly final sells and top-level sell lines (parent_sell_line_id = null) are returned.
Variation lookupvariation_id must belong to a business product; invalid ids return 404.
Price visibilityunit_price, discount_amount, item_tax, unit_sale_price, and subtotal are null without access_default_selling_price.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
variation_id, location_id, customer_id, customer_group_id, category_id, brand_idintegerNoOptional filters for the sell lines returned.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches product fields, customer fields, invoice numbers, POS contact ids, or numeric sell/sell-line ids.

ProductSellReportRow object

FieldTypeDescription
sell_line_id, transaction_id, invoice_no, transaction_datemixedSell-line and transaction identity fields.
product_name, product_display, product_type, product_custom_field1, product_custom_field2, sub_skumixedProduct identity fields.
customer, supplier_business_name, customer_display, contact_id, contact_no, contact_emailmixedCustomer fields.
sell_qty, unitmixedQuantity and unit fields.
unit_price, discount_type, discount_amount, discount_display, tax_name, item_tax, unit_sale_price, subtotalmixedPrice and tax fields, gated by selling-price visibility.
payment_methodsstring | nullSingle payment-method label, multi-pay label, or null.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.variation_id, data.location_id, data.customer_id, data.customer_group_id, data.category_id, data.brand_id, data.qmixedEchoes the applied filters.
data.itemsarray<ProductSellReportRow>The current page of sell-line rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The report rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks purchase_n_sell_report.view.{ "message": "Unauthorized" }
404variation_id does not belong to a product in the business.{ "message": "Variation not found" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The product-sell query failed unexpectedly.{ "message": "Could not load product sell report" }

Purchase payment report

Lists purchase and supplier opening-balance payments using the same payment query as the web Purchase Payment report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/purchase-payment-report
Permissionpurchase_n_sell_report.view.
Payment scopeIncludes purchase and supplier opening-balance payments, including split/child-payment relationships through the same EXISTS branch used by the web report.
Root-payment ruleWhen location_id is omitted, the main branch only includes rows where parent_id IS NULL.
CSV behaviorExports all matching payments and ignores pagination.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format payment-date range. Both must be sent together and start_date must not be after end_date.
location_id, supplier_idintegerNoOptional location and supplier filters.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches supplier display text, payment ref, purchase ref, method, cheque/card/bank/custom transaction fields, or numeric ids.

PurchasePaymentReportRow object

FieldTypeDescription
payment_id, payment_ref_no, paid_on, amountmixedPayment identity and amount fields.
method, method_label, method_detailmixedStored payment method, resolved label, and detail string for cheque/card/bank/custom rows.
supplier_display, purchase_ref_no, transaction_idmixedSupplier and linked purchase fields.
cheque_number, card_transaction_number, bank_account_number, custom_transaction_nostring | nullMethod-specific stored references.
document, document_urlstring | nullStored filename and resolved document URL when present.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.supplier_id, data.qmixedEchoes the applied filters.
data.itemsarray<PurchasePaymentReportRow>The current page of payment rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The payment rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks purchase_n_sell_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The purchase-payment query failed unexpectedly.{ "message": "Could not load purchase payment report" }

Sell payment report

Lists sell and customer opening-balance payments using the same payment query as the web Sell Payment report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/sell-payment-report
Permissionpurchase_n_sell_report.view.
Payment scopeIncludes sell and customer opening-balance payments, with the same split/child-payment logic as the web report.
Root-payment ruleWhen location_id is omitted, the main branch only includes rows where parent_id IS NULL.
Return handlingamount is negated when is_return = true, and method_detail appends the translated change-return label.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format payment-date range. Both must be sent together and start_date must not be after end_date.
location_id, customer_id, customer_group_idintegerNoOptional location, customer, and customer-group filters.
payment_typesstringNoExact payment-method key filter applied to transaction_payments.method.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches customer display text, contact fields, invoice number, payment ref, customer group name, method, transaction fields, or numeric ids.

SellPaymentReportRow object

FieldTypeDescription
payment_id, payment_ref_no, paid_on, amount, is_returnmixedPayment identity and signed amount fields.
method, method_label, method_detailmixedStored method, resolved label, and detail string.
customer_display, contact_id, customer_group, invoice_no, transaction_idmixedCustomer and linked sell fields.
cheque_number, card_transaction_number, bank_account_number, custom_transaction_nostring | nullMethod-specific stored references.
document, document_urlstring | nullStored filename and resolved document URL when present.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.customer_id, data.customer_group_id, data.payment_types, data.qmixedEchoes the applied filters.
data.itemsarray<SellPaymentReportRow>The current page of payment rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The payment rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks purchase_n_sell_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The sell-payment query failed unexpectedly.{ "message": "Could not load sell payment report" }

Expense report

Returns expense totals by category using the same aggregation as the web Expense report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/expense-report
Permissionexpense_report.view.
Default rangeThe current calendar month when dates are omitted.
Totalsexpense_refund amounts are subtracted from normal expense totals.
q behaviorFilters returned category rows; grand_total and chart are recomputed from the filtered items.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_idintegerNoOptional location filter.
expense_category_idintegerNoOptional single-category filter.
qstringNoMatches category label/name text or an exact numeric expense_category_id.

ExpenseReportRow object

FieldTypeDescription
expense_category_idinteger | nullCategory id or null for the "others" bucket.
category_namestring | nullStored category name when present.
category_labelstringDisplay label, including the translated "others" label for uncategorized rows.
total_expensenumberNet total for the category after subtracting refunds.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.expense_category_id, data.qmixedEchoes the resolved filters.
data.grand_totalnumberSum of total_expense across the current items set.
data.itemsarray<ExpenseReportRow>The category totals returned by the report.
data.chart.labels, data.chart.valuesarrayChart-ready arrays based on the filtered item list. JSON only.

Status codes

StatusWhen it happensResponse shape
200The expense report was returned successfully.{ "data": { ... } } or CSV download.
403The token user lacks expense_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The expense-report query failed unexpectedly.{ "message": "Could not load expense report" }

Register report

Lists cash-register sessions with payment totals by method using the same engine as the web Register report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/register-report
Permissionregister_report.view.
Data sourceTransactionUtil::registerReport().
Date behaviorWhen dates are omitted, no register-created date filter is applied.
JSON-only fielddata.payment_method_labels is included in JSON responses only and maps payment keys to labels.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_id, user_idintegerNoOptional location and register-user filters.
statusstringNoopen or close.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches location names, user names/emails, or numeric cash-register/user ids.

RegisterReportRow object

FieldTypeDescription
cash_register_id, status, location_id, location_name, user_id, user_displaymixedRegister identity and display fields.
created_at, closed_atstring | nullOpen/close timestamps. closed_at is only populated for closed sessions.
total_card_slips, total_chequesintegerSlip/cheque counts recorded on the session.
total_cash_payment, total_cheque_payment, total_card_payment, total_bank_transfer_payment, total_other_payment, total_advance_payment, total_custom_pay_1 ... total_custom_pay_7numberPayment totals by method.
payments_totalnumberTotal of all payment columns for the session.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.user_id, data.status, data.qmixedEchoes the applied filters.
data.payment_method_labelsobjectMap of payment method keys to display labels.
data.itemsarray<RegisterReportRow>The current page of register sessions.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The register rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks register_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The register-report query failed unexpectedly.{ "message": "Could not load register report" }

Sales representative report

Returns the sales representative summary cards used by the web report: expense totals, sell totals, and optional commission calculations.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/sales-representative
Permissionsales_representative.view.
Default rangeThe current calendar month when dates are omitted.
Commission behaviordata.commission is only populated when user_id is supplied. The base figure is controlled by POS setting cmmsn_calculation_type (invoice_value or payment_received).
q behaviorValidated and echoed in data.q only. It does not change totals.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_id, user_idintegerNoOptional location and representative filters.
qstringNoEcho-only search term.

SalesRepresentativeCommission object

FieldTypeDescription
commission_percentagenumberThe saved commission percentage on the selected user.
total_payment_with_commissionnumber | nullThe commission base when POS settings use payment received.
total_sales_with_commissionnumber | nullThe commission base when POS settings use invoice value.
total_commissionnumberCalculated commission amount for the chosen base.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.user_id, data.qmixedEchoes the resolved filters.
data.commission_calculation_type, data.payments_with_commission_tab_enabledmixedDerived from the business POS settings.
data.expense.total_expensenumberTotal expense attributed to the selected representative and filters.
data.sales.total_sell_exc_tax, data.sales.total_sell_return_exc_tax, data.sales.total_sellnumberSell totals used by the report cards.
data.commissionSalesRepresentativeCommission | nullCommission details when user_id is supplied.

Status codes

StatusWhen it happensResponse shape
200The summary was returned successfully.{ "data": { ... } } or single-row CSV download.
403The token user lacks sales_representative.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, user_id is invalid, or q is too short.Laravel validation JSON or { "message": string }.
500The sales-representative calculation failed unexpectedly.{ "message": "Could not load sales representative report" }

Table report (restaurant)

Aggregates final sell totals by restaurant table using the same query as the web Table report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/table-report
Permissionpurchase_n_sell_report.view.
Row scopeOnly tables attached to final sell transactions appear.
Date behaviorWhen dates are omitted, no date filter is applied.
CSV behaviorExports all matching tables and ignores pagination.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_idintegerNoOptional location filter.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches the restaurant table name or an exact numeric res_table_id.

TableReportRow object

FieldTypeDescription
res_table_idintegerRestaurant table id.
namestringRestaurant table name.
total_sellnumberFinal sell total aggregated for the table.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.qmixedEchoes the applied filters.
data.itemsarray<TableReportRow>The current page of aggregated table rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The table rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks purchase_n_sell_report.view.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, or q is too short.Laravel validation JSON or { "message": string }.
500The table-report query failed unexpectedly.{ "message": "Could not load table report" }

Service staff report

Returns either invoice-level service-staff orders or line-level service-staff line orders, matching the two web report datasets.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/service-staff-report
Permissionsales_representative.view.
Required datasetdataset=orders for invoice-level rows or dataset=line_orders for sell-line rows.
Date behaviororders uses start-of-day/end-of-day datetime filtering; line_orders filters by calendar dates on the sell transaction.
CSV behaviorExports all matching rows for the selected dataset and ignores pagination.

Query parameters

ParameterTypeRequiredDescription
datasetstringYesorders or line_orders.
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_id, service_staff_idintegerNoOptional location and service-staff filters.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches invoice/location/staff text for orders, or product/invoice/location/staff text for line_orders, plus numeric ids.

ServiceStaffOrderRow object

FieldTypeDescription
transaction_id, transaction_date, invoice_nomixedSell transaction identity fields.
res_waiter_id, waiter_display, business_locationmixedAssigned waiter and location fields.
total_before_tax, discount_amount, tax_amount, final_totalnumberInvoice-level totals for the order.

ServiceStaffLineOrderRow object

FieldTypeDescription
sell_line_id, transaction_id, transaction_date, invoice_nomixedSell-line identity fields.
business_location, res_service_staff_id, service_staff_displaymixedAssigned staff and location fields.
product_label, quantity, unitmixedLine item identity fields.
unit_price_before_discount, line_discount_amount, line_discount_type, item_tax, unit_price_inc_tax, line_totalmixedPricing and tax fields for the sell line.

Top-level JSON response

FieldTypeDescription
data.dataset, data.start_date, data.end_date, data.location_id, data.service_staff_id, data.qmixedEchoes the applied filters.
data.itemsarray<ServiceStaffOrderRow | ServiceStaffLineOrderRow>The current page of rows for the selected dataset.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The selected dataset was returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks sales_representative.view.{ "message": "Unauthorized" }
422dataset is missing or invalid, a date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The service-staff query failed unexpectedly.{ "message": "Could not load service staff report" }

GST sales report (India)

Returns India GST sales lines with dynamic per-tax columns, using the same line-level query as the web GST sales report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/gst-sales-report
Permissiontax_report.view.
Feature flagconfig('constants.enable_gst_report_india') must be enabled.
Row scopeOnly final sells and top-level sell lines (parent_sell_line_id = null) are included.
Dynamic columnsEach row includes tax_{id} keys for every non-group tax rate returned in data.tax_columns.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_id, customer_idintegerNoOptional location and customer filters.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches customer fields, invoice number, product fields, HSN short code, or numeric transaction/sell-line ids.

GstTaxColumn object

FieldTypeDescription
idintegerNon-group tax rate id.
namestringTax rate name.
amountnumber | nullConfigured tax percentage for the rate.

GstSalesReportRow object

FieldTypeDescription
sell_line_id, transaction_id, transaction_date, invoice_nomixedSell-line and invoice identity fields.
customer_display, contact_number, customer_tax_numbermixedCustomer identity fields.
hsn_short_code, quantity, unitmixedProduct/GST classification and quantity fields.
unit_price_before_discount, unit_price_after_discount, discount_amount, discount_type, taxable_value, tax_percent, is_tax_group, item_tax, line_totalmixedBase pricing and GST fields.
tax_{id}numberPer-rate GST amount for each entry in data.tax_columns.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.customer_id, data.qmixedEchoes the applied filters.
data.tax_columnsarray<GstTaxColumn>Defines the dynamic tax_{id} columns used in each row.
data.itemsarray<GstSalesReportRow>The current page of GST sales rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The GST sales rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks tax_report.view or India GST reporting is disabled.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The GST sales query failed unexpectedly.{ "message": "Could not load GST sales report" }

GST purchase report (India)

Returns India GST purchase lines with dynamic per-tax columns, using the same line-level query as the web GST purchase report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/gst-purchase-report
Permissiontax_report.view.
Feature flagconfig('constants.enable_gst_report_india') must be enabled.
Row scopeOnly purchase lines on received purchases are included.
Dynamic columnsEach row includes tax_{id} keys for every non-group tax rate returned in data.tax_columns.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_id, supplier_idintegerNoOptional location and supplier filters.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches supplier fields, purchase ref, product fields, HSN short code, or numeric transaction/purchase-line ids.

GstPurchaseReportRow object

FieldTypeDescription
purchase_line_id, transaction_id, transaction_date, ref_nomixedPurchase-line and transaction identity fields.
supplier_display, contact_number, supplier_tax_numbermixedSupplier identity fields.
hsn_short_code, quantity, unitmixedProduct/GST classification and quantity fields.
unit_price_before_discount, unit_price_after_discount, discount_amount, taxable_value, tax_percent, is_tax_group, item_tax, line_totalmixedBase pricing and GST fields.
tax_{id}numberPer-rate GST amount for each entry in data.tax_columns.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.supplier_id, data.qmixedEchoes the applied filters.
data.tax_columnsarray<GstTaxColumn>Defines the dynamic tax_{id} columns used in each row.
data.itemsarray<GstPurchaseReportRow>The current page of GST purchase rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The GST purchase rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks tax_report.view or India GST reporting is disabled.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The GST purchase query failed unexpectedly.{ "message": "Could not load GST purchase report" }

Purchase report 606 (regional)

Returns the regional purchase report 606 rows using the same transaction-level query as the web report when the feature is enabled.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/purchase-report-606
PermissionAt least one of purchase.view, purchase.create, or view_own_purchase.
Feature flagconfig('constants.show_report_606') must be enabled.
Own-only behaviorWhen the user lacks purchase.view but has view_own_purchase, rows are restricted to purchases created by that user.
Payment method labelBuilt from linked payment lines: a single label, the translated multi-pay label, or null.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
location_id, supplier_idintegerNoOptional location and supplier filters.
payment_statusstringNopaid, due, partial, or overdue. overdue uses the same pay-term SQL logic as the web report.
statusstringNoPurchase status key from ProductUtil::orderStatuses().
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches purchase ref, supplier fields, location name, or an exact numeric transaction id.

PurchaseReport606Row object

FieldTypeDescription
transaction_id, ref_nomixedPurchase identity fields.
supplier_name, contact_numberstring | nullSupplier display fields.
total_before_tax, discount_amount, tax_amount, final_totalnumberMain purchase totals.
purchase_year_month, purchase_daystring | nullPurchase date split into regional report columns.
payment_year_month, payment_daystring | nullDerived from the first payment line when one exists.
payment_methodstring | nullResolved payment method label.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.supplier_id, data.payment_status, data.status, data.qmixedEchoes the applied filters.
data.itemsarray<PurchaseReport606Row>The current page of regional purchase-report rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The report rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks the required purchase permission or the 606 report feature flag is disabled.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The purchase report 606 query failed unexpectedly.{ "message": "Could not load purchase report 606" }

Sale report 607 (regional)

Returns the regional sale report 607 rows using the same final-sell eligibility rules as the integration sell list when the feature is enabled.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/sale-report-607
PermissionAt least one of sell.view, sell.create, direct_sell.access, or view_own_sell_only.
Feature flagconfig('constants.show_report_607') must be enabled.
Eligibility rulesThe base query reuses the same final-sell visibility and payment-status restrictions as the integration sell list, including own-sell and commission-agent limits when direct_sell.view is absent.
is_direct_sale behaviorThe filter is only applied when the query parameter is present. 0 means non-direct sells with sub_type = null; 1 means direct sells only.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date. The query uses start-of-day/end-of-day datetime bounds.
location_id, contact_id, created_byintegerNoOptional location, customer contact, and creator filters.
payment_statusstringNopaid, due, partial, or overdue.
is_direct_salestringNo0 or 1. Ignored unless the parameter is present.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.
qstringNoMatches invoice number, customer fields, or numeric transaction/contact ids.

SaleReport607Row object

FieldTypeDescription
transaction_id, invoice_no, sale_datemixedSell identity fields.
contact_id, customer_displaystring | nullCustomer reference number and display label.
total_before_tax, discount_amount, tax_amount, final_totalnumberMain sell totals.
payment_methodsstring | nullResolved payment method label.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.location_id, data.contact_id, data.payment_status, data.created_by, data.is_direct_sale, data.qmixedEchoes the applied filters.
data.itemsarray<SaleReport607Row>The current page of regional sell-report rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata.

Status codes

StatusWhen it happensResponse shape
200The report rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user lacks the required sell permission or the 607 report feature flag is disabled.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The sale report 607 query failed unexpectedly.{ "message": "Could not load sale report 607" }

Activity log

Returns business activity-log rows using the same filters and structured note payloads as the web Activity Log report.

Endpoint summary

PropertyValue
MethodGET
Path/api/v1/integration/reports/activity-log
PermissionThe token user must be a business admin.
Text filtersSupports q or legacy search. The resolved value is returned as data.search and meta.q.
Structured fieldsnote is a structured payload equivalent to the web note column without HTML. changes comes directly from the activity properties.
CSV behaviorExports all matching rows and JSON-encodes note and changes into CSV cells.

Query parameters

ParameterTypeRequiredDescription
start_date, end_datestringConditionalBusiness-format dates. Both must be sent together and start_date must not be after end_date.
user_idintegerNoOptional causer filter.
subject_typestringNoOne of contact, user, sell, purchase, sales_order, purchase_order, sell_return, purchase_return, sell_transfer, stock_adjustment, or expense.
q, searchstringNoMatches activity description, causer display name, or numeric activity/subject ids.
per_page, pageintegerNoPagination controls. per_page accepts 1 to 100 and defaults to 20.

ActivityLogRow object

FieldTypeDescription
id, created_atmixedActivity identity and timestamp.
subject_type, subject_type_label, subject_idmixedRaw subject class, translated subject label, and subject id.
description, description_keymixedTranslated description text and its raw language key.
causer_id, causer_displaymixedCauser identity fields.
noteobject | nullStructured note payload, including refs, status transitions, transaction changes, or other context when present.
changesarray | object | nullRaw activity changes payload from the logger.

Top-level JSON response

FieldTypeDescription
data.start_date, data.end_date, data.user_id, data.subject_type, data.searchmixedEchoes the applied filters and resolved search term.
data.itemsarray<ActivityLogRow>The current page of activity-log rows.
meta.current_page, meta.last_page, meta.per_page, meta.total, meta.qmixedPagination metadata and the resolved search term.

Status codes

StatusWhen it happensResponse shape
200The activity-log rows were returned successfully.{ "data": { ... }, "meta": { ... } } or CSV download.
403The token user is not a business admin.{ "message": "Unauthorized" }
422The date pair is incomplete or reversed, a filter failed validation, or q is too short.Laravel validation JSON or { "message": string }.
500The activity-log query failed unexpectedly.{ "message": "Could not load activity log" }