Overview
The Luminous External V1 API provides two dedicated bulk-export endpoints — one for products and one for sales orders — that are designed for downloading large catalogs or running incremental syncs. Unlike the standard list endpoints (which use page/offset pagination and support rich filtering), the export endpoints use cursor-based keyset pagination: they are faster and more stable for large data sets, and each export run is anchored to a consistent snapshot so that records updated mid-run do not cause gaps or duplicates.
Products export
Endpoint: GET /external/api/v1/products/export
How it works
- First page — send a
sinceparameter (a date or UTC datetime, e.g.1970-01-01T00:00:00Zto get all active products). This anchors an internal cutoff timestamp so the entire export sees the same consistent snapshot. - Subsequent pages — drop
sinceand send thecursorvalue returned asnext_cursorin the previous response. Do not send both at the same time. - Keep paging until
has_moreisfalse.
Parameters
| Parameter | When to use | Notes |
|---|---|---|
since | First request only | ISO 8601 date or datetime, e.g. 1970-01-01 |
cursor | All follow-up requests | Opaque string — copy from next_cursor |
limit | Optional on any request | Default 100, maximum 1000 |
Response envelope
{
"data": [ ...product rows... ],
"next_cursor": "eyJ...",
"has_more": true,
"meta": {
"rows": 100,
"total_count": 5000 ← only present on the first page
}
}
total_countis only returned on the first page (when you sentsince). Use it to show a progress indicator.- Each product row includes core fields such as SKU, name, prices, weights, dimensions, alternate SKUs, tags, custom fields, kit items, and shallow BOM references.
What is NOT included in export rows
For performance reasons, the export omits: nested BOM line items, variant SKU child rows, attachments, substitutions, priority lists, and expanded unit conversion rules on alternate SKUs. To retrieve any of those, call GET /products/{id} for the specific product.
Sales orders export
Endpoint: GET /external/api/v1/sales-orders/export
How it works
The pattern is identical to the products export:
- First page — send
since(lower bound onupdated_at). - Subsequent pages — send
cursorcopied fromnext_cursor. Do not combine withsince. - Stop when
has_moreisfalse.
Parameters
| Parameter | When to use | Notes |
|---|---|---|
since | First request only | UTC date or datetime |
cursor | All follow-up requests | Opaque string from next_cursor |
limit | Optional | Default 1000, maximum 1000 |
Important: Only
since,cursor, andlimitare accepted as query parameters on this endpoint. Adding any other filter parameter will result in a validation error.
Response envelope
{
"data": [ ...sales order rows... ],
"next_cursor": "eyJ...",
"has_more": true,
"meta": { "rows": 1000 }
}
Choosing between export and list endpoints
| Export endpoint | List endpoint | |
|---|---|---|
| Use case | Full catalog download, incremental sync | Filtered/searched queries |
| Pagination | Cursor-based (fast, snapshot-consistent) | Offset/page-based |
| Filtering | Not supported — only since/cursor/limit | Full filter operators supported |
| Default page size | 100 (products) / 1000 (sales orders) | Up to 100 |
Use the list endpoint (GET /products or GET /sales-orders) when you need to filter by status, channel, date range, tags, etc. Use the export endpoint when you want to download everything or poll for all records updated since a known timestamp.
Incremental sync pattern
To keep an external system in sync without downloading everything each time:
- On the very first run, call the export with
since=1970-01-01T00:00:00Zand page through all records. Record the timestamp when you started. - On subsequent runs, pass that recorded timestamp as
since. Only records with anupdated_aton or after that timestamp will be returned. - After completing a run, update your stored timestamp to the start of the latest run.
Authentication
All External API requests require a bearer token:
Authorization: Bearer {your_api_token}
API tokens are managed in the Luminous admin under the API token settings.
Common errors
| Status | Meaning |
|---|---|
400 | Invalid or tampered cursor string |
401 | Missing or invalid bearer token |
422 | Validation failure — e.g. sending both since and cursor together, or an unsupported query parameter |