Skip to content

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)

{
  "message": "Inventory item successfully deleted."
}

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