Inventory (Inventories)¶
The Inventory API manages all test equipment and measuring instruments in the system.
Endpoints¶
| Method | Path | Description | Permission |
|---|---|---|---|
GET |
/api/v2/inventories |
List all inventory items | inventory_view |
GET |
/api/v2/inventories/{id} |
Retrieve a single inventory item | inventory_view |
POST |
/api/v2/inventories |
Create an inventory item | inventory_edit |
PUT |
/api/v2/inventories/{id} |
Update an inventory item | inventory_edit |
DELETE |
/api/v2/inventories/{id} |
Delete an inventory item | inventory_delete |
Field Mapping¶
Every field has three identifiers: the V1 code (metrology / MetTrack code
such as I4206), the DB column (physical column name such as
serial_number), and the API name — the identifier the API speaks to the
outside world (in response fields, in filter[...], in sort, and as a grid
column).
| V1 Code | DB Column | Description |
|---|---|---|
I4201 |
asset_number |
Asset number |
I4202 |
manufacturer |
Manufacturer |
I4203 |
model |
Model |
I4204 |
description |
Description |
I4206 |
serial_number |
Serial number |
Choosing the API name: V1 code or DB column¶
Which identifier serves as the API name is configurable. Existing customers
integrate against the V1 codes, so the V1 code is the default: the API
returns and accepts fields under their code (e.g. I4206 instead of
serial_number). The stored value stays untouched in its physical DB column;
only the outward-facing field name changes.
In Field management (Admin → Field definitions) two bulk actions are
available per table (permission field_management_admin):
- "API name = V1 code" — sets every field's API name to its V1 code
(
serial_number→I4206). This is the factory default. - "API name = DB column" — sets the API name to the readable DB column name
(
I4206→serial_number).
Programmatically this maps to:
curl -X POST "https://example.com/api/v2/field-definitions/inventory/copy-api-name" \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{ "source": "v1_name" }' # or "column_name"
Examples on this page
The examples below use the readable names (serial_number,
manufacturer). When the V1 code is the active API name, the codes take
their place everywhere (I4206, I4202) — in request and response
fields as well as in filter[...] and sort.
List All Inventory Items¶
curl -X GET "https://example.com/api/v2/inventories?page=1&per_page=25" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Query Parameters¶
| Parameter | Type | Description |
|---|---|---|
page |
integer | Page number (default: 1) |
per_page |
integer | Items per page (default: 25) |
sort |
string | Sort field, e.g. inventory_number or -manufacturer (descending) |
filter[manufacturer] |
string | Filter by manufacturer |
filter[serial_number] |
string | Filter by serial number |
filter[customer_id] |
integer | Filter by customer |
fields |
string | Comma-separated list of the fields the response should carry |
Ask only for the fields you need
Without fields, every row carries the installation's complete attribute
set — on a grown registry that is upwards of a hundred fields per row.
?fields=asset_number,manufacturer,status narrows it, and not just the
response: the server then loads only the relations and reads only the
columns those fields need.
A field is addressable by its api_name, its physical column name or its V1
code. Derived values travel with their field: customer_id brings
customer_id_label, status brings status_label. Filtering and sorting
may still name fields that were not requested.
Response¶
{
"data": [
{
"id": 1,
"inventory_number": "PM-2024-001",
"manufacturer": "Fluke",
"model": "8845A",
"serial_number": "SN-123456",
"customer_id": 5,
"relationships": {
"customer": {
"id": 5,
"name": "Mustermann GmbH"
},
"calibrations": [
{ "id": 12, "calibration_date": "2024-06-15" }
],
"categories": [
{ "id": 3, "name": "Multimeter" }
]
}
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total": 142,
"last_page": 6
},
"links": {
"first": "/api/v2/inventories?page=1",
"last": "/api/v2/inventories?page=6",
"next": "/api/v2/inventories?page=2",
"prev": null
}
}
Retrieve a Single Inventory Item¶
curl -X GET "https://example.com/api/v2/inventories/1" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
The response contains the complete inventory object in the data field, including all relationships (Customer, Calibrations, Categories).
Create an Inventory Item¶
curl -X POST "https://example.com/api/v2/inventories" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"inventory_number": "PM-2024-002",
"manufacturer": "Keysight",
"model": "34461A",
"serial_number": "MY-987654",
"customer_id": 5
}'
Required Fields
At minimum, inventory_number must be provided. All other fields are optional but recommended.
Successful Response (201)¶
{
"data": {
"id": 2,
"inventory_number": "PM-2024-002",
"manufacturer": "Keysight",
"model": "34461A",
"serial_number": "MY-987654",
"customer_id": 5
}
}
Update an Inventory Item¶
curl -X PUT "https://example.com/api/v2/inventories/2" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"manufacturer": "Keysight Technologies",
"serial_number": "MY-987654-A"
}'
Partial Updates
Only the fields to be changed need to be sent. Fields not included remain unchanged.
Delete an Inventory Item¶
curl -X DELETE "https://example.com/api/v2/inventories/2" \
-H "Authorization: Bearer {token}" \
-H "Accept: application/json"
Caution
Deleting an inventory item also removes all associated calibrations and documents. This action cannot be undone.
Successful Response (200)¶
Sorting and Filtering¶
Sorting Examples¶
# Ascending by inventory number
curl "https://example.com/api/v2/inventories?sort=inventory_number" \
-H "Authorization: Bearer {token}"
# Descending by manufacturer
curl "https://example.com/api/v2/inventories?sort=-manufacturer" \
-H "Authorization: Bearer {token}"
Filter Examples¶
# Only Fluke devices
curl "https://example.com/api/v2/inventories?filter[manufacturer]=Fluke" \
-H "Authorization: Bearer {token}"
# Devices of a specific customer
curl "https://example.com/api/v2/inventories?filter[customer_id]=5&sort=-inventory_number" \
-H "Authorization: Bearer {token}"
Error Codes¶
| HTTP Status | Meaning |
|---|---|
401 |
Not authenticated — invalid or missing token |
403 |
Insufficient permissions (inventory_view, inventory_edit, or inventory_delete missing) |
404 |
Inventory item not found |
422 |
Validation error — invalid or missing fields |
429 |
Rate limit exceeded |