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:

  1. As a header: X-Inventora-API-Key: your_api_key_here
  2. 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 (requires customStatusId)

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 (requires customStatusId)

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:

  • pieces
  • bundles (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"
}