Inventora API Documentation
Authentication
All API requests require authentication using an API key. You can obtain an API key by visiting Settings > Developers
Include your API key in one of two ways:
- As a header:
X-Inventora-API-Key: your_api_key_here - As a query parameter:
?x-inventora-api-key=your_api_key_here
Base URL
https://api.inventora.com/api
Endpoints
Get Products
GET /products
Returns a paginated list of products.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
| limit | number | 100 | Maximum number of results (max: 1000) |
| offset | number | 0 | Number of results to skip |
Response:
{
"data": [
{
"id": "asdf123",
"name": "Handmade Candle",
"sku": "CANDLE-001",
"stockLevel": 45,
"unitType": "pieces",
"unitPrice": 5.50,
"minLevel": 10,
"notes": "Vanilla scented",
"retailPrice": 15.00,
"wholesalePrice": 10.00,
"ean": "1234567890123",
"minimumQuantity": 1,
"reorderURLs": ["https://example.com/reorder"],
"locationStockLevels": {
"Main Warehouse": 30,
"Retail Store": 15
},
"productionType": "produced",
"materials": [
{
"id": "asdf456",
"name": "Soy Wax",
"sku": "WAX-SOY",
"unitType": "weight.lbs",
"unitPrice": 3.25,
"stockLevel": 100,
"minLevel": 20,
"quantityUsed": 0.5
}
]
}
],
"pagination": {
"totalCount": 150,
"offset": 0,
"limit": 100
}
}
Get Product
GET /products/:id
Returns a single product by ID.
Response:
{
"id": "asdf123",
"name": "Handmade Candle",
"sku": "CANDLE-001",
"stockLevel": 45,
"unitType": "pieces",
"unitPrice": 5.50,
"minLevel": 10,
"notes": "Vanilla scented",
"retailPrice": 15.00,
"wholesalePrice": 10.00,
"ean": "1234567890123",
"minimumQuantity": 1,
"reorderURLs": ["https://example.com/reorder"],
"locationStockLevels": {
"Main Warehouse": 30,
"Retail Store": 15
},
"productionType": "produced",
"materials": [
{
"id": "asdf456",
"name": "Soy Wax",
"sku": "WAX-SOY",
"unitType": "weight.lbs",
"unitPrice": 3.25,
"stockLevel": 100,
"minLevel": 20,
"quantityUsed": 0.5
}
]
}
Get Materials
GET /materials
Returns a paginated list of materials.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
| limit | number | 100 | Maximum number of results (max: 1000) |
| offset | number | 0 | Number of results to skip |
Response:
{
"data": [
{
"id": "asdf456",
"name": "Soy Wax",
"sku": "WAX-SOY",
"stockLevel": 100,
"unitType": "weight.lbs",
"unitPrice": 3.25,
"minLevel": 20,
"notes": "Food grade soy wax",
"retailPrice": null,
"wholesalePrice": null,
"ean": "9876543210987",
"minimumQuantity": 10,
"reorderURLs": ["https://supplier.com/wax"],
"locationStockLevels": {
"Main Warehouse": 80,
"Production Floor": 20
},
"productionType": "supplied",
"materials": []
}
],
"pagination": {
"totalCount": 75,
"offset": 0,
"limit": 100
}
}
Get Material
GET /materials/:id
Returns a single material by ID.
Response:
{
"id": "asdf456",
"name": "Soy Wax",
"sku": "WAX-SOY",
"stockLevel": 100,
"unitType": "weight.lbs",
"unitPrice": 3.25,
"minLevel": 20,
"notes": "Food grade soy wax",
"retailPrice": null,
"wholesalePrice": null,
"ean": "9876543210987",
"minimumQuantity": 10,
"reorderURLs": ["https://supplier.com/wax"],
"locationStockLevels": {
"Main Warehouse": 80,
"Production Floor": 20
},
"productionType": "supplied",
"materials": []
}
Update Product
PATCH /products/:id
Updates a product.
Request Body:
{
"name": "Updated Product Name",
"sku": "NEW-SKU",
"unitType": "pieces",
"unitPrice": 6.00,
"minLevel": 15,
"notes": "Updated notes",
"retailPrice": 18.00,
"wholesalePrice": 12.00,
"ean": "1234567890124",
"minimumQuantity": 2,
"reorderURLs": ["https://example.com/reorder-new"]
}
All fields are optional. Only include fields you want to update.
Note: unitPrice can only be updated if the resource has no stock blocks tied to non-initial logs. The unitType field cannot be changed to or from bundle.
Response:
{
"id": "asdf123",
"name": "Updated Product Name",
"sku": "NEW-SKU",
"stockLevel": 45,
"unitType": "pieces",
"unitPrice": 6.00,
"minLevel": 15,
"notes": "Updated notes",
"retailPrice": 18.00,
"wholesalePrice": 12.00,
"ean": "1234567890124",
"minimumQuantity": 2,
"reorderURLs": ["https://example.com/reorder-new"],
"locationStockLevels": {
"Main Warehouse": 30,
"Retail Store": 15
},
"productionType": "produced",
"materials": [
{
"id": "asdf456",
"name": "Soy Wax",
"sku": "WAX-SOY",
"unitType": "weight.lbs",
"unitPrice": 3.25,
"stockLevel": 100,
"minLevel": 20,
"quantityUsed": 0.5
}
]
}
Update Material
PATCH /materials/:id
Updates a material.
Request Body:
{
"name": "Updated Material Name",
"sku": "NEW-MAT-SKU",
"unitType": "weight.kg",
"unitPrice": 4.00,
"minLevel": 25,
"notes": "Updated material notes",
"retailPrice": null,
"wholesalePrice": null,
"ean": "9876543210988",
"minimumQuantity": 15,
"reorderURLs": ["https://supplier.com/wax-new"]
}
All fields are optional. Only include fields you want to update.
Note: unitPrice can only be updated if the resource has no stock blocks tied to non-initial logs. The unitType field cannot be changed to or from bundle.
Response:
{
"id": "asdf456",
"name": "Updated Material Name",
"sku": "NEW-MAT-SKU",
"stockLevel": 100,
"unitType": "weight.kg",
"unitPrice": 4.00,
"minLevel": 25,
"notes": "Updated material notes",
"retailPrice": null,
"wholesalePrice": null,
"ean": "9876543210988",
"minimumQuantity": 15,
"reorderURLs": ["https://supplier.com/wax-new"],
"locationStockLevels": {
"Main Warehouse": 80,
"Production Floor": 20
},
"productionType": "supplied",
"materials": []
}
Update Product Stock Level
POST /products/:id/stock-level-updates
Updates the stock level of a product at a specific location.
Request Body:
{
"quantity": 10,
"locationName": "Main Warehouse",
"updateType": "audit",
"notes": "Weekly inventory count",
"customStatusId": null
}
Fields:
| Field | Type | Required | Description |
|---|---|---|---|
| quantity | number | Yes | The quantity to set or adjust |
| locationName | string | Yes | Name of the location |
| updateType | string | Yes | One of: audit, restock, loss, custom |
| notes | string | No | Optional notes about the update |
| customStatusId | number | Conditional | Required when updateType is custom |
Update Types:
audit: Sets the stock level to the exact quantity specified (absolute value)restock: Adds the quantity to current stock level (adjustment)loss: Subtracts the quantity from current stock level (adjustment)custom: Uses a custom status (requirescustomStatusId)
Response:
{
"id": "asdf123",
"name": "Handmade Candle",
"sku": "CANDLE-001",
"stockLevel": 55,
"unitType": "pieces",
"unitPrice": 5.50,
"minLevel": 10,
"notes": "Vanilla scented",
"retailPrice": 15.00,
"wholesalePrice": 10.00,
"ean": "1234567890123",
"minimumQuantity": 1,
"reorderURLs": ["https://example.com/reorder"],
"locationStockLevels": {
"Main Warehouse": 40,
"Retail Store": 15
},
"productionType": "produced",
"materials": [
{
"id": "asdf456",
"name": "Soy Wax",
"sku": "WAX-SOY",
"unitType": "weight.lbs",
"unitPrice": 3.25,
"stockLevel": 100,
"minLevel": 20,
"quantityUsed": 0.5
}
]
}
Update Material Stock Level
POST /materials/:id/stock-level-updates
Updates the stock level of a material at a specific location.
Request Body:
{
"quantity": 50,
"locationName": "Main Warehouse",
"updateType": "restock",
"notes": "Received shipment from supplier",
"customStatusId": null
}
Fields:
| Field | Type | Required | Description |
|---|---|---|---|
| quantity | number | Yes | The quantity to set or adjust |
| locationName | string | Yes | Name of the location |
| updateType | string | Yes | One of: audit, restock, loss, custom |
| notes | string | No | Optional notes about the update |
| customStatusId | number | Conditional | Required when updateType is custom |
Update Types:
audit: Sets the stock level to the exact quantity specified (absolute value)restock: Adds the quantity to current stock level (adjustment)loss: Subtracts the quantity from current stock level (adjustment)custom: Uses a custom status (requirescustomStatusId)
Response:
{
"id": "asdf456",
"name": "Soy Wax",
"sku": "WAX-SOY",
"stockLevel": 150,
"unitType": "weight.lbs",
"unitPrice": 3.25,
"minLevel": 20,
"notes": "Food grade soy wax",
"retailPrice": null,
"wholesalePrice": null,
"ean": "9876543210987",
"minimumQuantity": 10,
"reorderURLs": ["https://supplier.com/wax"],
"locationStockLevels": {
"Main Warehouse": 130,
"Production Floor": 20
},
"productionType": "supplied",
"materials": []
}
Get Locations
GET /locations
Returns a paginated list of locations.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
| limit | number | 100 | Maximum number of results (max: 1000) |
| offset | number | 0 | Number of results to skip |
Response:
{
"data": [
{
"id": "loc_789",
"name": "Main Warehouse",
"isDefault": true,
"hideMaterials": false,
"address1": "123 Storage St",
"address2": "Unit 5",
"city": "Portland",
"state": "OR",
"zip": "97201",
"country": "US"
},
{
"id": "loc_790",
"name": "Retail Store",
"isDefault": false,
"hideMaterials": true,
"address1": "456 Main St",
"address2": null,
"city": "Portland",
"state": "OR",
"zip": "97202",
"country": "US"
}
],
"pagination": {
"totalCount": 2,
"offset": 0,
"limit": 100
}
}
Get Tasks
GET /tasks
Returns a paginated list of tasks.
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
| limit | number | 100 | Maximum number of results (max: 1000) |
| offset | number | 0 | Number of results to skip |
| status | string | - | Filter by task status: pending, in-progress, done |
| UserId | string | - | Filter by user ID or email address |
Response:
{
"data": [
{
"id": "task_123",
"name": "Produce 50 Candles",
"status": "pending",
"order": 1,
"LocationId": "loc_789",
"UserId": "user_456",
"due": "2024-03-15T10:00:00Z",
"completedAt": null,
"notes": "Rush order for weekend market",
"createdAt": "2024-03-01T09:00:00Z",
"updatedAt": "2024-03-01T09:00:00Z",
"Items": [
{
"id": 1,
"ResourceId": "asdf123",
"quantity": 50,
"unitType": "pieces",
"completed": false,
"Product": {
"id": "asdf123",
"name": "Handmade Candle",
"sku": "CANDLE-001",
"unitType": "pieces",
"stockLevel": 45,
"type": "product"
},
"Batches": []
}
]
}
],
"pagination": {
"totalCount": 25,
"offset": 0,
"limit": 100
}
}
Get Task
GET /tasks/:id
Returns a single task by ID.
Response:
{
"id": "task_123",
"name": "Produce 50 Candles",
"status": "pending",
"order": 1,
"LocationId": "loc_789",
"UserId": "user_456",
"due": "2024-03-15T10:00:00Z",
"completedAt": null,
"notes": "Rush order for weekend market",
"createdAt": "2024-03-01T09:00:00Z",
"updatedAt": "2024-03-01T09:00:00Z",
"Items": [
{
"id": 1,
"ResourceId": "asdf123",
"quantity": 50,
"unitType": "pieces",
"completed": false,
"Product": {
"id": "asdf123",
"name": "Handmade Candle",
"sku": "CANDLE-001",
"unitType": "pieces",
"stockLevel": 45,
"type": "product"
},
"Batches": [
{
"id": 1,
"UserId": "user_456",
"quantity": 25,
"createdAt": "2024-03-02T14:30:00Z",
"updatedAt": "2024-03-02T14:30:00Z"
}
]
}
]
}
Create Task
POST /tasks
Creates a new task.
Request Body:
{
"name": "Produce 50 Candles",
"Assignee": "user@example.com",
"Items": [
{
"ProductId": "asdf123",
"quantity": 50,
"unitType": "pieces"
}
],
"LocationId": "loc_789",
"due": "2024-03-15T10:00:00Z",
"notes": "Rush order for weekend market",
"status": "pending"
}
Fields:
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Task name |
| Assignee | string | No | User ID or email address to assign task to |
| UserId | string | No | Alternative to Assignee - user ID to assign task to |
| Items | array | Yes | Array of task items (cannot be empty) |
| Items[].ProductId | string | Yes | Product/resource ID |
| Items[].quantity | number | Yes | Quantity to produce (must be > 0) |
| Items[].unitType | string | No | Unit type (defaults to "pieces") |
| LocationId | string | No | Location ID where task should be performed |
| due | string | No | Due date (ISO 8601 format) |
| notes | string | No | Optional notes |
| status | string | No | Task status: pending, in-progress, done (defaults to "pending") |
Response:
{
"id": "task_123",
"name": "Produce 50 Candles",
"status": "pending",
"order": 1,
"LocationId": "loc_789",
"UserId": "user_456",
"due": "2024-03-15T10:00:00Z",
"completedAt": null,
"notes": "Rush order for weekend market",
"createdAt": "2024-03-01T09:00:00Z",
"updatedAt": "2024-03-01T09:00:00Z",
"Items": [
{
"id": 1,
"ResourceId": "asdf123",
"quantity": 50,
"unitType": "pieces",
"completed": false,
"Product": {
"id": "asdf123",
"name": "Handmade Candle",
"sku": "CANDLE-001",
"unitType": "pieces",
"stockLevel": 45,
"type": "product"
},
"Batches": []
}
]
}
Update Task
PATCH /tasks/:id
Updates an existing task.
Request Body:
{
"name": "Produce 75 Candles",
"Assignee": "newuser@example.com",
"status": "in-progress",
"LocationId": "loc_790",
"due": "2024-03-16T10:00:00Z",
"notes": "Updated quantity and deadline"
}
Fields:
All fields are optional. Only include fields you want to update.
| Field | Type | Description |
|---|---|---|
| name | string | Task name (cannot be empty) |
| Assignee | string | User ID or email address to assign task to (null to unassign) |
| UserId | string | Alternative to Assignee - user ID to assign task to (null to unassign) |
| status | string | Task status: pending, in-progress, done |
| LocationId | string | Location ID where task should be performed (null to unset) |
| due | string | Due date (ISO 8601 format, null to unset) |
| notes | string | Optional notes (null to unset) |
Response:
{
"id": "task_123",
"name": "Produce 75 Candles",
"status": "in-progress",
"order": 1,
"LocationId": "loc_790",
"UserId": "user_789",
"due": "2024-03-16T10:00:00Z",
"completedAt": null,
"notes": "Updated quantity and deadline",
"createdAt": "2024-03-01T09:00:00Z",
"updatedAt": "2024-03-01T15:30:00Z",
"Items": [
{
"id": 1,
"ResourceId": "asdf123",
"quantity": 50,
"unitType": "pieces",
"completed": false,
"Product": {
"id": "asdf123",
"name": "Handmade Candle",
"sku": "CANDLE-001",
"unitType": "pieces",
"stockLevel": 45,
"type": "product"
},
"Batches": []
}
]
}
Delete Task
DELETE /tasks/:id
Deletes a task (soft delete).
Response:
Returns 204 No Content on success.
Create Task Batch
POST /tasks/:id/items/:item_id/batches
Creates a production batch for a specific task item.
Request Body:
{
"quantity": 25
}
Fields:
| Field | Type | Required | Description |
|---|---|---|---|
| quantity | number | Yes | Quantity to produce in this batch (must be > 0) |
Response:
{
"id": 1,
"TaskResourceId": 1,
"UserId": null,
"quantity": 25,
"createdAt": "2024-03-02T14:30:00Z",
"updatedAt": "2024-03-02T14:30:00Z"
}
Delete Task Batch
DELETE /task-batches/:id
Deletes a task batch and reverses its production.
Response:
Returns 204 No Content on success.
Type Definitions
productionType
One of: infinite, single, produced, supplied, bundle
unitType
One of:
piecesbundles(read-only, cannot be set or changed)cases- Weight:
weight.lbs,weight.oz,weight.kg,weight.grams,weight.mg,weight.ct,weight.gr - Length:
length.ft,length.yd,length.in,length.m,length.cm,length.mm - Area:
area.sqft,area.sqin,area.sqm,area.sqcm - Volume:
volume.oz,volume.pt,volume.qt,volume.ga,volume.ml,volume.liters,volume.bdft,volume.cuin,volume.cuft,volume.cuyd,volume.cm3,volume.m3,volume.tsp,volume.tbsp,volume.cup - Time:
time.seconds,time.minutes,time.hours,time.days
Error Responses
All endpoints may return the following error responses:
401 Unauthorized:
{
"error": "API key missing"
}
{
"error": "Invalid API key"
}
404 Not Found:
{
"error": "String describing error"
}
400 Bad Request:
{
"error": "String describing error"
}