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
403usually 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/locationsendpoint ignores themaxparameter 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#
- Authentication: create an API key and authenticate requests with
X-API-Key - Products API: query and manage your product catalog
- Stock Movements: create and track shipments between locations
- Generic CRUD API: access any domain object through a uniform interface
- Reporting API: read the Reports page's figures into Power BI, Excel or your own code