API Overview

The OpenBoxes REST API provides programmatic access to your supply chain data hosted on OpenBoxes Lift. Use it to integrate with ERPs, build custom dashboards, automate workflows, and synchronize inventory across systems.

Base URL#

Data API requests are scoped to your tenant subdomain:

https://{subdomain}.openboxes.cloud/api/v1

Webhook management is the exception and lives on the platform API host:

https://api.openboxes.cloud/api/v1/webhooks

It needs an API key carrying the admin scope. See Webhooks.

The Reporting API is the second exception and lives on the same platform host:

https://api.openboxes.cloud/api/v1/reporting

It serves the Reports page's figures (stock on hand, stock value, expiring lots, open purchase orders and activity) as read-only datasets, from our daily check rather than your live data. See Reporting API.

For example, if your instance is acme.openboxes.cloud, your base URL is:

https://acme.openboxes.cloud/api/v1

How we verify what is on these pages#

OpenBoxes is open-source software we host; its API is not ours, and we will not document an endpoint we cannot stand behind. Every endpoint on these pages is in one of three states, and we say which:

  • Verified on Lift: we have a captured request and response from a real instance. These pages show that capture. Unless a section says otherwise, this is what you are reading.
  • Not yet verified on Lift: the endpoint is in the OpenBoxes API reference and the application source, and nothing on our side blocks it, but we have not captured it ourselves. Sections like this carry a note saying so. Test the call against a trial instance before you build on it (a staging copy will not do, because API keys are refused against one), and tell support if it behaves differently than described.
  • Not available: it is absent from these pages entirely, and where you would reasonably look for it you will find one sentence saying where that job is done instead. Purchase-order writes are the main example.

Our captures come from the OpenBoxes web application's own requests on a hosted instance. A call made with an API key reaches the same endpoints, but it runs as the key's creator (the person who created the key), at the location Lift resolves for that person (their default location, if one is set) rather than one picked in a browser. For reads that makes no difference; where a write depends on the current location, test it with your own key before you rely on it.

If an endpoint is not on these pages, we have not verified it. That is not the same as saying it does not work. It means you should not build on it without checking with us first.

Request Format#

The API accepts and returns JSON. Authenticate every request with the X-API-Key header (see Authentication). Include the following headers with every request:

Header Value Required
X-API-Key YOUR_API_KEY Yes
Content-Type application/json Yes (POST/PUT)
Accept application/json Recommended

Response Format#

Successful responses return JSON with an HTTP 200 status. The response shape varies by endpoint. OpenBoxes is not uniform here, so check the page for each endpoint you use and test against your instance. Many list endpoints (for example /api/v1/products) wrap results in a data envelope, sometimes with a totalCount:

{
  "data": [
    { "id": "abc123", "name": "Ibuprofen 200mg" },
    { "id": "def456", "name": "Paracetamol 500mg" }
  ],
  "totalCount": 2
}

Others return a bare JSON array:

[
  { "id": "abc123", "name": "Ibuprofen 200mg" },
  { "id": "def456", "name": "Paracetamol 500mg" }
]

Single-resource endpoints typically return the object under data; the Generic API wraps its responses in the same envelope:

{
  "data": {
    "id": "abc123",
    "name": "Ibuprofen 200mg",
    "productCode": "IBU200"
  }
}

Error Responses#

When a request to the OpenBoxes data API fails, it returns an appropriate HTTP status code with error details:

{
  "errorCode": 400,
  "errorMessage": "Validation failed",
  "errors": [
    { "field": "name", "message": "Property [name] cannot be null" }
  ]
}

The platform API host (webhook management and the Reporting API) answers errors in a different, simpler shape: {"error": "<code>", "message": "<one sentence>"}.

Common error codes:

Status Code Meaning
400 Bad request: missing or invalid parameters
401 Unauthorized: invalid or missing API key
402 Reporting API: the account is suspended
403 Forbidden: the key is not valid for this tenant, or it lacks the scope that endpoint requires
404 Not found: resource does not exist
405 Reporting API: only GET and HEAD are answered
409 Reporting API: values were turned on or off for the key while you were paging; start again
410 Reporting API: the page you asked for is no longer available; start again
429 Rate limit exceeded
500 Internal server error
503 A maintenance window is open, or its state could not be confirmed: your request was not forwarded and can be retried. See Maintenance Windows. On the Reporting API, the data could not be loaded just now; retry after Retry-After.

Note: A 403 usually means the key was used against a subdomain it does not belong to, because keys are scoped to a single tenant. On webhook management it also means the key lacks the required scope (insufficient_scope) or has no tenant binding (api_key_no_tenant_binding). On the Reporting API it means the key has no tenant binding (api_key_no_tenant_binding), or, once scopes are enforced, that its scopes do not allow the request. See Authentication, Webhooks and Reporting API.

Pagination#

List endpoints on the OpenBoxes data API support pagination via query parameters:

Parameter Type Default Description
offset integer 0 Number of records to skip
max integer all Maximum number of records to return

Example: fetch products 21 through 30:

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

Known Limitation: Pagination behavior is inconsistent across some endpoints. The /api/v1/locations endpoint ignores the max parameter and always returns all results. Test pagination behavior for each endpoint you use.

The Reporting API pages differently: with a cursor rather than offset and max. Pass each response's nextCursor back until it is empty.

API Versioning#

All endpoints are accessed under the /api/v1/ path prefix on your tenant subdomain. Breaking changes are introduced behind a new version prefix; non-breaking additions are communicated via release notes and the Lift platform changelog.

Rate Limiting#

All API requests are subject to rate limits based on your Lift subscription tier:

Tier Requests per Hour
Shared 1,000
Dedicated 25,000
Enterprise 50,000

An API add-on raises the hourly allowance: API 2× or 5× on Shared, API 2× on Dedicated, purchased under Billing > Add-ons in the portal; Enterprise bands are contract line items. See Rate Limits for prices and details.

Rate limit status is returned in response headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 847
X-RateLimit-Reset: 1700000000

When you exceed the limit, the API returns HTTP 429 Too Many Requests. See the Rate Limits page for best practices.

The Reporting API has its own separate allowance of 600 requests an hour on every plan, so reporting never uses up the limits above.

Content Types#

The OpenBoxes data API works with JSON. XML or form-encoded requests are not supported on API endpoints. Always set:

Content-Type: application/json

The Reporting API can also answer in CSV (format=csv).

Next Steps#