Overview
The Luminous External V1 API exposes a full cycle count lifecycle under /external/api/v1/pickflow/cycle-counts/.... You can create batches, record physical quantities, submit for review, post inventory adjustments, and manage batch or session records entirely programmatically — using the same API token your other External API integrations already use.
Auth:
Authorization: Bearer {api_token}on every request. Tenancy is resolved from the request hostname.
1. Estimate scope before creating
Before committing to a batch, check how many items your scope would produce:
GET /external/api/v1/pickflow/cycle-counts/sku-estimate
?warehouse_ids[]=42
&category_ids[]=7
Use /bin-location-estimate if you plan to count by bin location. Both accept the same selection filters as the create call and return a count per warehouse without writing anything.
2. Create a batch
POST /external/api/v1/pickflow/cycle-counts
Content-Type: application/json
{
"warehouse_ids": [42],
"count_mode": "sku",
"is_blind_count": false,
"remarks": "Scheduled Q3 count"
}
Returns 201 with the batch and its per-warehouse sessions (all start in draft status).
Key create fields:
| Field | Notes |
|---|---|
warehouse_ids | Required for warehouse-first (default) scope. |
count_mode | sku (default) or bin_location. |
location_ids | Specific bin locations within the selected warehouses (bin-location mode). |
product_ids / lot_ids | Product-first or lot-first scope (requires the expanded scoping feature on your account — contact support). |
category_ids, preferred_vendor_ids | Optional narrowing filters. |
is_blind_count | Hides system on-hand quantities from counters. |
name, remarks | Optional labels. |
If some selected products or lots had no stock, the batch is still created for the valid selections and a warning field describes what was dropped.
3. Session lifecycle
Each batch contains one counting session per warehouse. Move a session through its states:
| Action | Endpoint | Transition |
|---|---|---|
| Start counting | POST .../sessions/{sessionId}/start | draft → in_progress |
| Submit for review | POST .../sessions/{sessionId}/submit-review | in_progress → pending_review |
| Reopen for corrections | POST .../sessions/{sessionId}/reopen | pending_review → in_progress |
| Post adjustment | POST .../sessions/{sessionId}/post | pending_review → posted |
| Cancel | POST .../sessions/{sessionId}/cancel | any non-posted → cancelled |
All lifecycle calls except post take no body.
4. Record counts
While a session is in_progress, record physical quantities per item:
POST /external/api/v1/pickflow/cycle-counts/{sessionId}/items/{itemId}/count
{ "quantity": 48 }
Or use the barcode scan endpoint (POST .../scan) to look up an item by SKU/barcode and record its count in one step.
Retrieve the item list (paginated) at:
GET /external/api/v1/pickflow/cycle-counts/{sessionId}/items
5. CSV import (bulk count entry)
For large sessions, download a count-sheet template, fill it in, and import:
-
Download template (session must be
in_progress):GET /external/api/v1/pickflow/cycle-counts/{sessionId}/templateReturns a
.csvfile with one row per item to count. -
Validate before committing (
multipart/form-data, field namefile):POST /external/api/v1/pickflow/cycle-counts/{sessionId}/validate-importReturns matched rows, unmatched rows, and any invalid rows — no changes are written yet.
-
Apply the import using the
matched_itemsmap from step 2:POST /external/api/v1/pickflow/cycle-counts/{sessionId}/import-counts { "matched_items": { "1042": 15, "1043": 0 } }
6. Post the adjustment — read this first
POST .../sessions/{sessionId}/post creates a real, irreversible inventory adjustment. Every counted item with a non-zero variance becomes a stock adjustment entry.
Required body:
{ "confirm": true }
Omitting confirm: true returns 422. The API enforces race-condition safety — two concurrent post calls for the same session serialize correctly; the second sees the already-posted status and is rejected.
There is no dry-run mode. If a session should not be posted, use cancel instead.
Recommendation: Get explicit sign-off before enabling automated posting in production. A script that posts the wrong session creates a real inventory adjustment with no built-in undo through the API.
7. Batch management
GET /external/api/v1/pickflow/cycle-counts/batches # paginated list
GET /external/api/v1/pickflow/cycle-counts/batches/{batchId} # detail
POST /external/api/v1/pickflow/cycle-counts/batches/{batchId}/start-all # start all draft sessions
GET /external/api/v1/pickflow/cycle-counts/batches/{batchId}/export # variance report CSV
DELETE /external/api/v1/pickflow/cycle-counts/batches/{batchId} # requires { "confirm": true }
Deleting a batch is irreversible from the API's point of view. Batches with any posted session cannot be deleted.
8. Export variance reports
GET /external/api/v1/pickflow/cycle-counts/{sessionId}/export
Returns a CSV variance report (all items, expected vs. counted, variance) as a direct file download — the same report available from the UI's Review screen.
Rate limits
| Action | Limit |
|---|---|
| Create, start, submit-review, reopen, cancel, reset-counts | 60 requests / minute |
| Bulk start-all, validate-import, import-counts | 30 requests / minute |
| Post, delete (batch or session) | 10 requests / minute |
| All read / export endpoints | Unthrottled |
Exceeding the limit returns 429 Too Many Requests.
Feature-flag parity
The API enforces the same feature flags as the UI. Scope modes your account can't access in the UI return 403 externally. If your account doesn't have bin-location counting or the expanded product/lot scoping enabled, those options are not available via the API either. Contact Luminous Support to request access.
OpenAPI spec
A machine-readable OpenAPI 3 spec is available for import into Swagger UI or code generation — ask your Luminous account team for the spec file or the developer documentation link.
Additional help
For integration questions or to request expanded scoping features, contact Luminous Support through the help center chat or at support@joinluminous.com.