Stock catalog fields and lookups
List stock picker rows by category
/a/Stock_listByCategory
Return active, unarchived stock as positional picker rows, optionally restricted by category and legacy supplier.
When to use this endpoint
Use for CRM1 stock selection in purchase orders, invoices, quotes and job tables. The row shape is intentionally positional rather than mapped objects.
Authentication and permissions
Authenticate with signed API-key fields or a logged-in CRM session. The handler calls the user-login guard but adds no stock-page, finance or administrator permission check.
Queries use the authenticated tenant. Sign numeric values as strings; JSON-encode only parameters described as JSON text. See Getting started.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | Integer-compatible string | No | Category ID, not stock ID. Omitted/zero means all categories. Nonzero uses the active category’s stored stock membership CSV; missing category or empty membership returns [] immediately. |
supplier_id | Integer-compatible string | No | Nonzero filters stock.supplier_id, not stock_suppliers or many-to-many relationships. Omitted/zero removes this filter. |
fields | Native array or JSON array text | No | Accepted order: any supplied names from id, name, code, in_stock, average_cost, price, nominal_code, tax_rate, price_bands. Invalid/malformed or wholly unrecognized selection falls back to id,name,code. ID is not added to a valid projection. |
Example request
$items = FM_api('Stock_listByCategory', ['id'=>'1088', 'fields'=>json_encode(['id','name','code'])]);
Example response
[["1042","Filter cartridge","FLT-01"]]
Errors and unusual responses
| Response | Condition |
|---|---|
{"error":"not logged in"} | No authenticated tenant context is available. Invalid signed credentials can be rejected by the dispatcher before the handler runs. |
[] | No eligible category membership or filtered rows. |
{"error":"supplier not linked to any stock"} | No selected rows and a nonzero supplier_id has no non-deleted, unarchived stock anywhere. The early missing/empty category return bypasses this check. |
Legacy application errors may be returned with HTTP 200. Check the decoded response for error, not only the HTTP status.
Behaviour and edge cases
- Filters stock.deleted=0 and is_archived=0; the category lookup also filters deleted=0. Does not recursively include child categories.
- Orders by name, with no paging or tie-breaker. Output positions follow distinct selected SQL fields; repeated column names collapse in the associative database row before conversion to positions. Names/types are not enriched and price_bands remains encoded JSON.
- If the supplier has eligible stock outside this category, an empty category result is [] rather than the supplier error. Does not validate the supplier itself.
- Reads category.stock membership, not category_ids JSON on each stock row. No page/finance or feature-setting guard is enforced.
- No direct mobile caller was found in the current app JavaScript or
m/wwwintermediary. The app receives stock throughsyncDownloads, which selects non-deleted stock by edit timestamp; these calls are not the app synchronization protocol.
Side effects
- Read-only; no audit, edit timestamp, event or stock movement.
See it in Fieldmotion
CRM1
In a purchase-order line, open the stock picker and change category. Stock_listByCategory receives category id, supplier_id and JSON fields; the same positional picker is used by invoice, quote costs and job table screens.
CRM2
No direct CRM2 browser caller was found for this exact endpoint; the Stocks module uses mapped Stock reads and writes.
Related endpoints
Stock_listBySupplieruses the same scalar supplier assignment but returns object rows.StockCategory_getreads a category and its membership.