Products API

The Products API lets you manage your product catalog: listing, searching, creating, and updating products in your OpenBoxes instance.

List Products#

Retrieve a paginated list of products. A single q parameter searches across name, product code, description, manufacturer, and vendor fields.

curl -H "X-API-Key: $OB_API_KEY" \
  "https://acme.openboxes.cloud/api/v1/products?max=10&offset=0"

Query Parameters#

Parameter Type Default Description
max integer all Maximum number of products to return
offset integer 0 Number of records to skip
q string None Search term matched against name, product code, description, manufacturer, and vendor (partial match)
includeInactive boolean false Include deactivated products

Search Example#

curl -H "X-API-Key: $OB_API_KEY" \
  "https://acme.openboxes.cloud/api/v1/products?q=ibuprofen&max=25"

Response#

List responses are wrapped in a data envelope with a totalCount of all matching products (not just the page returned), so you can paginate with max and offset:

{
  "data": [
    {
      "id": "ff808181648b61df01648b7000000001",
      "productCode": "IBU200",
      "name": "Ibuprofen 200mg",
      "description": "Anti-inflammatory tablet",
      "category": {
        "id": "cat-001",
        "name": "Pharmaceuticals"
      },
      "unitOfMeasure": "EA",
      "dateCreated": "2025-01-15T10:30:00Z",
      "lastUpdated": "2025-03-20T14:22:00Z"
    }
  ],
  "totalCount": 550
}

Get Product by ID#

Retrieve a single product with full details:

curl -H "X-API-Key: $OB_API_KEY" \
  "https://acme.openboxes.cloud/api/v1/products/ff808181648b61df01648b7000000001"

Response#

{
  "data": {
    "id": "ff808181648b61df01648b7000000001",
    "productCode": "IBU200",
    "name": "Ibuprofen 200mg",
    "description": "Anti-inflammatory tablet",
    "category": {
      "id": "cat-001",
      "name": "Pharmaceuticals"
    },
    "unitOfMeasure": "EA",
    "manufacturer": "PharmaCorp",
    "manufacturerCode": "PC-IBU-200",
    "pricePerUnit": 0.15,
    "coldChain": false,
    "active": true
  }
}

Create Product#

Create a new product in the catalog:

curl -X POST \
  -H "X-API-Key: $OB_API_KEY" \
  -H "Content-Type: application/json" \
  "https://acme.openboxes.cloud/api/v1/products" \
  -d '{
    "name": "Amoxicillin 250mg Capsules",
    "productCode": "AMOX250",
    "description": "Antibiotic capsule for oral administration",
    "category": { "id": "cat-001" },
    "productType": { "id": "DEFAULT" },
    "unitOfMeasure": "EA",
    "manufacturer": "GenericPharma",
    "coldChain": false
  }'

A successful create answers 200 (not 201) and returns the new record under a product key ({ "product": { "id": "...", ... } }), unlike most endpoints, which use data. A productCode that already exists is refused with 400 and a validation error naming productCode.

productType is required: without it the create is refused with 400 and a validation error naming productType. DEFAULT is the standard product type on a new instance; list the others with GET /api/v1/generic/productType.

Creating a product resolves the key creator's current location and validates against it, the same dependency stock-movement create has. Set a Default location on the key's owner before you rely on this call (see Locations).

Required Fields#

Field Type Description
name string Product display name
category object Category reference with id
productType object Product type reference with id (use DEFAULT unless your instance defines others)

Optional Fields#

Field Type Description
productCode string Unique product code (auto-generated if omitted)
description string Detailed product description
unitOfMeasure string Unit of measure (e.g., EA, CS, BX)
manufacturer string Manufacturer name
manufacturerCode string Manufacturer's product code
coldChain boolean Whether product requires cold chain storage
pricePerUnit number Default price per unit

Update Product#

The /products endpoint itself does not accept updates. Update an existing product by ID through the generic CRUD API instead:

curl -X PUT \
  -H "X-API-Key: $OB_API_KEY" \
  -H "Content-Type: application/json" \
  "https://acme.openboxes.cloud/api/v1/generic/product/ff808181648b61df01648b7000000001" \
  -d '{
    "description": "Anti-inflammatory tablet, 200mg strength",
    "pricePerUnit": 0.18
  }'

Only include the fields you want to update. Omitted fields remain unchanged.

Documented from the OpenBoxes API reference and the application source; we have not captured this call on a hosted instance. Test it against a trial instance before you build on it, and tell support if it behaves differently.

Get Available Items#

Retrieve inventory items (lot/batch records) available for a specific product:

curl -H "X-API-Key: $OB_API_KEY" \
  "https://acme.openboxes.cloud/api/v1/products/ff808181648b61df01648b7000000001/availableItems"

Results are scoped to the key creator's current location; pass location.id=<location-id> to query a different one.

Response#

{
  "data": [
    {
      "inventoryItem": {
        "id": "inv-001",
        "lotNumber": "LOT-2025-001",
        "expirationDate": "2026-06-30T00:00:00Z"
      },
      "quantityAvailable": 5000,
      "quantityOnHand": 5200
    }
  ]
}

Product Associations#

Retrieve products associated with a given product (substitutes, equivalents):

curl -H "X-API-Key: $OB_API_KEY" \
  "https://acme.openboxes.cloud/api/v1/products/ff808181648b61df01648b7000000001/associatedProducts"

Documented from the OpenBoxes API reference and the application source; we have not captured this call on a hosted instance. Test it against a trial instance before you build on it, and tell support if it behaves differently.

Important Notes#

  • Products are global: Products are not scoped to a specific location or organization. Any product created is visible across all locations within your tenant.
  • Category required: Every product must belong to a category. Retrieve available categories via /api/v1/generic/category before creating products.
  • Product codes: If you provide a productCode, it must be unique across your entire instance. If omitted, OpenBoxes auto-generates one.
  • Deletion: Product deletion is generally not supported if the product has any associated inventory transactions. Deactivate products by setting active: false instead.
  • Product search endpoint: OpenBoxes also answers GET /api/v1/products/search, which this page does not document. On Shared and Dedicated alike it accepts only GET and HEAD, and it refuses a name or q value containing a backslash (\) with a 400 and the response header X-Lift-Denied: param-shape. Use q on the list endpoint above instead.