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:

FieldNotes
warehouse_idsRequired for warehouse-first (default) scope.
count_modesku (default) or bin_location.
location_idsSpecific bin locations within the selected warehouses (bin-location mode).
product_ids / lot_idsProduct-first or lot-first scope (requires the expanded scoping feature on your account — contact support).
category_ids, preferred_vendor_idsOptional narrowing filters.
is_blind_countHides system on-hand quantities from counters.
name, remarksOptional 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:

ActionEndpointTransition
Start countingPOST .../sessions/{sessionId}/startdraft → in_progress
Submit for reviewPOST .../sessions/{sessionId}/submit-reviewin_progress → pending_review
Reopen for correctionsPOST .../sessions/{sessionId}/reopenpending_review → in_progress
Post adjustmentPOST .../sessions/{sessionId}/postpending_review → posted
CancelPOST .../sessions/{sessionId}/cancelany 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:

  1. Download template (session must be in_progress):

    GET /external/api/v1/pickflow/cycle-counts/{sessionId}/template
    

    Returns a .csv file with one row per item to count.

  2. Validate before committing (multipart/form-data, field name file):

    POST /external/api/v1/pickflow/cycle-counts/{sessionId}/validate-import
    

    Returns matched rows, unmatched rows, and any invalid rows — no changes are written yet.

  3. Apply the import using the matched_items map 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

ActionLimit
Create, start, submit-review, reopen, cancel, reset-counts60 requests / minute
Bulk start-all, validate-import, import-counts30 requests / minute
Post, delete (batch or session)10 requests / minute
All read / export endpointsUnthrottled

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.