Integrate Inventory Now with your own applications, automations, and third-party services.
Your key will look like: inv_api_a1b2c3d4e5f67890_aBcDeFgHiJkLmNoPqRsTuVwXyZ...
Include your key in the Authorization header as a Bearer token. JSON responses are automatic when using an API key — no need to set Content-Type or Accept headers.
curl -X GET "https://www.inventorynow.app/items" \ -H "Authorization: Bearer YOUR_API_KEY"
All successful responses return JSON. Errors return a JSON object with an error or success: false field and an appropriate HTTP status code.
| Status Code | Meaning |
|---|---|
200 | Success |
400 | Bad request / validation error |
403 | Unauthorized / invalid or revoked API key |
404 | Resource not found |
500 | Server error |
GET /itemsReturns a paginated list of your inventory items.
| Param | Type | Description |
|---|---|---|
page | Integer | Page number (default: 1) |
per_page | Integer | Items per page (default: 50) |
search | String | Search across name, category, subcategory, location, notes, barcode, SKU |
category | String | Filter by exact category (case-insensitive) |
subcategory | String | Filter by exact subcategory (case-insensitive) |
location | String | Filter by exact location (case-insensitive) |
from_date | Date | Filter items with date on or after this value |
to_date | Date | Filter items with date on or before this value |
sort | String | Sort field: name, category, subcategory, place, updated_at, created_at, bought, sold, cost, paid (default: updated_at) |
dir | String | asc or desc (default: desc) |
Array of item objects:
[
{
"id": 123,
"name": "Widget A",
"category": "Electronics",
"subcategory": "Adapters",
"place": "Warehouse 1",
"notes": "Fragile, handle with care",
"barcode": "1234567890",
"sku": "WIDGET-A",
"internal_id": "abc-def-123",
"data_set": null,
"date": "2025-06-01T00:00:00.000Z",
"bought": 100.0,
"sold": 25.0,
"received": 100.0,
"shipped": 25.0,
"delivered": 25.0,
"loss": 2.0,
"cost": 500.0,
"paid": 750.0,
"unit_cost_buy": 5.0,
"unit_cost_sell": 30.0,
"low_stock_threshold": 10.0,
"complete": false,
"completed_at": null,
"deleted": false,
"image_name": "https://example.com/photo.jpg",
"custom_one": "Color: Red",
"custom_two": "Size: Large",
"custom_three": null,
"created_at": "2025-06-01T12:00:00.000Z",
"updated_at": "2025-06-15T08:30:00.000Z"
}
]
GET /items/:idReturns a single item by ID, including its photos.
{
"id": 123,
"name": "Widget A",
... (same fields as above),
"item_photos": [
{
"id": 1,
"item_id": 123,
"external_image_url": "https://example.com/photo.jpg",
"order_index": 0,
"created_at": "2025-06-01T12:00:00.000Z",
"updated_at": "2025-06-01T12:00:00.000Z"
}
]
}
POST /itemsCreates a new inventory item. If an item with the same internal_id already exists, it will be updated instead.
bought, sold, cost, paid) directly through this endpoint. Changes made here do not create order records, which means your order history and reports will be inaccurate. Use the Buy & Sell Order endpoints below to modify stock properly.
| Field | Type | Required | Description |
|---|---|---|---|
name | String | No* | Item name (*auto-generated if blank) |
category | String | No | Category grouping |
subcategory | String | No | Subcategory grouping |
place | String | No | Storage location |
notes | String | No | Free-text notes |
barcode | String | No | Barcode / UPC value |
sku | String | No | SKU identifier |
internal_id | String | No | Your unique ID (used for upsert matching) |
data_set | String | No | Dataset name (for multi-dataset accounts) |
date | DateTime | No | Item date (e.g. purchase date) |
bought | Decimal | No | Quantity purchased (default: 0) |
sold | Decimal | No | Quantity sold (default: 0) |
received | Decimal | No | Quantity received (default: 0) |
shipped | Decimal | No | Quantity shipped (default: 0) |
delivered | Decimal | No | Quantity delivered (default: 0) |
loss | Decimal | No | Quantity lost / shrinkage (default: 0) |
cost | Decimal | No | Total cost paid for stock (default: 0) |
paid | Decimal | No | Total revenue received from sales (default: 0) |
unit_cost_buy | Decimal | No | Default unit purchase cost |
unit_cost_sell | Decimal | No | Default unit sale price |
low_stock_threshold | Decimal | No | Per-item low-stock alert threshold |
complete | Boolean | No | Whether item is marked complete |
image_name | String | No | Primary image URL |
custom_one | String | No | Custom field 1 |
custom_two | String | No | Custom field 2 |
custom_three | String | No | Custom field 3 |
curl -X POST "https://www.inventorynow.app/items" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"item": {
"name": "Widget A",
"sku": "WIDGET-A",
"category": "Electronics",
"place": "Warehouse 1",
"bought": 100,
"cost": 500.00,
"unit_cost_buy": 5.00,
"unit_cost_sell": 30.00
}
}'
Returns the created item object (same shape as GET /items/:id, without item_photos).
PUT /items/:idUpdates an existing item. Only the fields you include in the request body will be changed.
bought, sold, cost, paid) directly through this endpoint. Changes made here do not create order records, which means your order history and reports will be inaccurate. Use the Buy & Sell Order endpoints below to modify stock properly.
Same fields as POST /items (all optional). Wrap in an "item" key.
curl -X PUT "https://www.inventorynow.app/items/123" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"item": {
"sold": 30,
"paid": 900.00,
"notes": "Restocked on June 20"
}
}'
Returns the updated item object.
DELETE /items/:idSoft-deletes an item (sets deleted: true). The item will no longer appear in lists.
{ "result": "success" }
PUT /items/:id/moveMoves a quantity of stock to a different location. If an item with the same name/category/subcategory exists at the target location, it merges. Otherwise, a new item is created.
| Field | Type | Required | Description |
|---|---|---|---|
location | String | Yes | Target location name |
quantity | Decimal | Yes | Quantity to move |
move_costs | Boolean | No | Whether to move proportional costs |
GET /items/summaryReturns a summary of your inventory metrics.
{
"sum": 1234
}
The sum value is a computed aggregate of (bought − sold − cost + paid + 1) across all non-deleted items.
Orders represent purchase (buy) and sale (sell) transactions against your items.
GET /ordersReturns a paginated list of orders (excludes cancelled).
| Param | Type | Description |
|---|---|---|
page | Integer | Page number (default: 1) |
order_type | String | Filter by buy or sell |
item_id | Integer | Filter orders containing this item |
assigned_user_id | Integer | Filter by assigned fulfillment user |
search | String | Search across item names, categories, locations, customer info |
[
{
"id": 456,
"order_type": "sell",
"notes": "Shipped via FedEx",
"customer_info": "Jane Doe, 123 Main St",
"tax_rate": 8.25,
"discount_rate": 0.0,
"fees": 5.0,
"paid": true,
"cancelled": false,
"completed_at": "2025-06-15T14:00:00.000Z",
"user_id": 1,
"created_by_user_id": 1,
"assigned_user_id": null,
"created_at": "2025-06-15T12:00:00.000Z",
"updated_at": "2025-06-15T14:00:00.000Z",
"order_items": [
{
"id": 789,
"order_id": 456,
"item_id": 123,
"quantity": 5.0,
"cost": 150.0,
"item_name": "Widget A",
"item": { "id": 123, "name": "Widget A", ... }
}
],
"created_by_user": { "id": 1, "username": "owner", ... },
"assigned_user": null
}
]
GET /orders/:idReturns a single order with its line items, related items, and assigned user.
Same shape as a single element from the list above.
When using an API key, creating an order automatically updates item stock counts — incrementing bought/cost for buy orders, or sold/paid for sell orders. You can disable this by passing ?adjust_item=false.
To explicitly control: POST /orders?adjust_item=true or POST /orders?adjust_item=false
POST /items/:item_id/orders — Buy OrderCreates a buy (purchase) order for the specified item. This records that you are purchasing stock.
| Field | Type | Required | Description |
|---|---|---|---|
order[order_type] | String | Yes | Must be "buy" |
order[notes] | String | No | Order notes |
order[customer_info] | String | No | Supplier / vendor info |
order[tax_rate] | Decimal | No | Tax rate as percentage (e.g. 8.25) |
order[discount_rate] | Decimal | No | Discount rate as percentage |
order[fees] | Decimal | No | Additional fees |
order[order_items_attributes] | Array | Yes | Line items (see below) |
| Field | Type | Required | Description |
|---|---|---|---|
item_id | Integer | Yes | ID of the item being purchased |
quantity | Decimal | Yes | Quantity to purchase (must be > 0) |
cost | Decimal | No | Total cost for this line (defaults to quantity × item's unit_cost_buy) |
curl -X POST "https://www.inventorynow.app/items/123/orders" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"order": {
"order_type": "buy",
"notes": "Restocking from supplier",
"order_items_attributes": [
{ "item_id": 123, "quantity": 50, "cost": 250.00 }
]
}
}'
Returns the created order object (same shape as GET /orders/:id).
POST /items/:item_id/orders — Sell OrderCreates a sell (sale) order for the specified item. This records a sale of stock to a customer.
Same structure as the buy order, but set order_type to "sell". The cost defaults to quantity × item's unit_cost_sell if omitted.
curl -X POST "https://www.inventorynow.app/items/123/orders" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"order": {
"order_type": "sell",
"customer_info": "Jane Doe, jane@example.com",
"tax_rate": 8.25,
"order_items_attributes": [
{ "item_id": 123, "quantity": 10, "cost": 300.00 }
]
}
}'
POST /orders — Multi-Item OrderCreate an order with multiple items in a single request. Works for both buy and sell orders.
curl -X POST "https://www.inventorynow.app/orders" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"order": {
"order_type": "sell",
"customer_info": "Acme Corp",
"tax_rate": 7.0,
"discount_rate": 5.0,
"fees": 10.00,
"order_items_attributes": [
{ "item_id": 123, "quantity": 5, "cost": 150.00 },
{ "item_id": 456, "quantity": 3, "cost": 90.00 }
]
}
}'
PUT /orders/:id/completeMarks an order as completed and paid. Updates lifecycle tracking fields if enabled in your settings (e.g. increments received for buy orders when "Track Received" is on, or shipped for sell orders when "Track Shipped" is on).
Returns the updated order object.
PUT /orders/:id/cancelCancels an order and reverses any stock adjustments that were made.
Returns the cancelled order object.
Add or remove individual line items from an existing order. The order must not be completed or cancelled.
When using an API key, adding or removing order items automatically updates item stock counts by default. Pass ?adjust_item=false to disable.
POST /order_itemsAdds a line item to an existing order.
| Field | Type | Required | Description |
|---|---|---|---|
order_id | Integer | Yes | ID of the order to add the item to |
item_id | Integer | Yes | ID of the item |
quantity | Decimal | Yes | Quantity (must be > 0) |
cost | Decimal | No | Total cost for this line (defaults to quantity × item's unit cost) |
| Param | Type | Description |
|---|---|---|
adjust_item | Boolean | Override stock adjustment (default: true for API key auth) |
curl -X POST "https://www.inventorynow.app/order_items" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{
"order_id": 456,
"item_id": 123,
"quantity": 5,
"cost": 75.00
}'
{
"id": 890,
"order_id": 456,
"item_id": 123,
"quantity": 5.0,
"cost": 75.0,
"item_name": "Widget A",
"item": { "id": 123, "name": "Widget A", ... }
}
DELETE /order_items/:idRemoves a line item from its order. If it was the last item, the order is also deleted.
| Param | Type | Description |
|---|---|---|
adjust_item | Boolean | Override stock reversal (default: true for API key auth) |
curl -X DELETE "https://www.inventorynow.app/order_items/890" \ -H "Authorization: Bearer YOUR_API_KEY"
{
"success": true
}
If the deleted item was the last on the order, the order is also destroyed and the response reflects that.
GET /user_settingsReturns your account settings (currency, labels, lifecycle toggles, etc.).
{
"id": 1,
"user_id": 1,
"category_name": "Category",
"subcategory_name": "Subcategory",
"location_name": "Location",
"currency_symbol": "$",
"low_stock_threshold": 5.0,
"received_status_enabled": true,
"shipped_status_enabled": true,
"delivered_status_enabled": false,
"back_orders_enabled": false,
"auto_complete_enabled": false,
"check_in_status_enabled": false,
"track_loss": true,
"hide_complete": false,
"custom_one_name": "Color",
"custom_two_name": "Size",
"custom_three_name": null,
"company_name": "Acme Inc",
"company_info": "123 Main St, Springfield",
"invoice_info": "Thank you for your business!",
"data_set": null,
...
}
PUT /user_settingsUpdates your account settings. Only include the fields you want to change.
{
"user_setting": {
"currency_symbol": "€",
"low_stock_threshold": 10,
"custom_one_name": "Material"
}
}
All errors return a JSON object. The format varies slightly by endpoint but will always include an error indicator:
// Validation / bad request (400)
{ "success": false, "error": "Invalid Quantity Entered." }
// Unauthorized (403)
{ "result": "failure. invalid permissions" }
// Server error (500)
{ "error": "Something went wrong" }
const API_KEY = "inv_api_your_key_here";
const BASE_URL = "https://www.inventorynow.app";
// List items
const items = await fetch(`${BASE_URL}/items?page=1`, {
headers: { "Authorization": `Bearer ${API_KEY}` }
}).then(r => r.json());
// Create a sell order (stock adjustment is automatic with API keys)
const order = await fetch(`${BASE_URL}/orders`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"Authorization": `Bearer ${API_KEY}`
},
body: JSON.stringify({
order: {
order_type: "sell",
customer_info: "Jane Doe",
order_items_attributes: [
{ item_id: items[0].id, quantity: 2, cost: 60.00 }
]
}
})
}).then(r => r.json());