# InventoryMod API Reference — Inventory & Warehouse REST API

> InventoryMod HTTP API reference: products, variants, kits, warehouses, stock movements, reservations, sales and purchase orders, imports and reports. Quick start, parameters, request bodies and response examples for every method.

Source: https://inventorymod.com/api-docs/

🔌 Developer API

An HTTP API for integrations: products, warehouses, stock, orders, purchasing and reports. Create an API key in the web app: user menu → “API keys”.

## Quick start

### 1. Get a key

In the [web app](https://app.inventorymod.com/), open the user menu → “API keys” and create a key. A `read` key can only read; a `write` key can read and write. The same dialog shows your `campaign_id` — the workspace the key belongs to; every request needs it.

### 2. Make your first request

Every method lives at `/api/rpc/<group>/<action>`. Reads use GET with parameters in the query string:

```
curl "https://app.inventorymod.com/api/rpc/products/search?campaign_id=1&limit=20&offset=0" \
  -H "Authorization: Bearer sk_test_…"
```

### 3. Write data

Writes use POST with a `write` key in a header (`Authorization: Bearer …` or `X-API-Key`) and a JSON body:

```
curl -X POST "https://app.inventorymod.com/api/rpc/products/create?campaign_id=1" \
  -H "Authorization: Bearer sk_live_…" \
  -H "Content-Type: application/json" \
  -d '{"product": {"name": "Blue T-shirt", "sku": "TS-BLUE-M"}}'
```

### 4. Responses and errors

A successful response is always `{ "data": … }`. Search methods take `limit` and `offset` and return `{ items, totalCount }`:

```
{ "data": { "items": [ … ], "totalCount": 120 } }
```

Errors come with an HTTP status and `{ "error": "…" }`, sometimes with a machine-readable `code` and `details`:

```
{ "error": "products/create requires a key with write scope" }
```

- **400** — invalid parameters or a business rule violation
- **401** — missing or revoked key
- **403** — the key has no access to the workspace, or the method needs the `write` scope
- **404 / 405** — unknown method or wrong HTTP method
- **429** — more than 300 requests per minute; the `RateLimit` header tells you when to retry

### 5. OpenAPI specification

The whole API as an OpenAPI 3.1 document: [openapi.json](https://inventorymod.com/openapi.json). Import it into Postman, Insomnia or a client generator.

## Products

Catalog items: create, update, search and delete products, look them up by SKU or barcode.

### List products

GET `products/list`

List products, optionally filtered by category, manufacturer, currency or kind. Variant parents (models) are excluded by default; pass includeParents: true to include them.

`GET https://app.inventorymod.com/api/rpc/products/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| categoryId | integer | no |  |
| manufacturerId | integer | no |  |
| currencyId | integer | no |  |
| isArchived | boolean | no |  |
| kinds | string | no |  |
| includeParents | boolean | no |  |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "sku": "ABC-1",
      "barcode": "CODE",
      "name": "Sample",
      "manufacturerId": 1,
      "categoryId": 1,
      "price": 9.99,
      "priceOld": 9.99,
      "rrp": 9.99,
      "currencyId": 1,
      "purchaseCost": 9.99,
      "purchaseCostCurrencyId": 1,
      "url": "string",
      "imageUrl": "string",
      "minQty": 9.99,
      "customFieldValues": {},
      "isArchived": false,
      "kind": "simple",
      "laborCost": 9.99,
      "laborCostCurrencyId": 1,
      "componentsUpdatedAt": "2026-01-01T00:00:00.000Z",
      "parentId": 1,
      "variantKey": "string",
      "nameLocked": false,
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Search products

GET `products/search`

Paginated product list with filters, search, stock status and sorting, plus the total count.

`GET https://app.inventorymod.com/api/rpc/products/search?campaign_id=1&limit=50&offset=0`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| search | string | no |  |
| categoryId | integer | no |  |
| manufacturerId | integer | no |  |
| currencyId | integer | no |  |
| isArchived | boolean | no |  |
| stockStatus | string all \| in \| out \| low | no |  |
| limit | integer | **yes** |  |
| offset | integer | **yes** |  |
| sortBy | string name \| sku \| price \| isArchived \| updatedAtUtc | no |  |
| sortCustomFieldId | string | no |  |
| sortOrder | string asc \| desc | no |  |
| lite | boolean | no |  |
| kinds | string | no |  |
| variantMode | string grouped \| flat \| all | no |  |
| parentId | integer | no |  |
| parentIsNull | boolean | no |  |

Response:

```
{
  "data": {
    "items": [
      {
        "id": 1,
        "campaignId": 1,
        "sku": "ABC-1",
        "barcode": "CODE",
        "name": "Sample",
        "manufacturerId": 1,
        "categoryId": 1,
        "price": 9.99,
        "priceOld": 9.99,
        "rrp": 9.99,
        "currencyId": 1,
        "purchaseCost": 9.99,
        "purchaseCostCurrencyId": 1,
        "url": "string",
        "imageUrl": "string",
        "minQty": 9.99,
        "customFieldValues": {},
        "isArchived": false,
        "kind": "simple",
        "laborCost": 9.99,
        "laborCostCurrencyId": 1,
        "componentsUpdatedAt": "2026-01-01T00:00:00.000Z",
        "parentId": 1,
        "variantKey": "string",
        "nameLocked": false,
        "createdAtUtc": "2026-01-01T00:00:00.000Z",
        "updatedAtUtc": "2026-01-01T00:00:00.000Z"
      }
    ],
    "totalCount": 1
  }
}
```

### Change product kind

POST `products/setKind`

Change the product kind. This is the only way to change the kind of an existing product.

`POST https://app.inventorymod.com/api/rpc/products/setKind?campaign_id=1&productId=1&kind=x`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| productId | integer | **yes** |  |
| kind | string | **yes** |  |

Request body (JSON):

```
{
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Get kind change facts

GET `products/kindFacts`

Facts about a product that determine which kind changes are allowed.

`GET https://app.inventorymod.com/api/rpc/products/kindFacts?campaign_id=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Export products

GET `products/exportPage`

Export products in batches using keyset pagination (id > afterId). Includes archived products, ordered by id.

`GET https://app.inventorymod.com/api/rpc/products/exportPage?campaign_id=1&limit=50`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| afterId | integer | no |  |
| limit | integer | **yes** |  |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "sku": "ABC-1",
      "barcode": "CODE",
      "name": "Sample",
      "manufacturerId": 1,
      "categoryId": 1,
      "price": 9.99,
      "priceOld": 9.99,
      "rrp": 9.99,
      "currencyId": 1,
      "purchaseCost": 9.99,
      "purchaseCostCurrencyId": 1,
      "url": "string",
      "imageUrl": "string",
      "minQty": 9.99,
      "customFieldValues": {},
      "isArchived": false,
      "kind": "simple",
      "laborCost": 9.99,
      "laborCostCurrencyId": 1,
      "componentsUpdatedAt": "2026-01-01T00:00:00.000Z",
      "parentId": 1,
      "variantKey": "string",
      "nameLocked": false,
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Get product info for an order line

GET `products/orderInfo`

Price, currency and available stock per warehouse for an order line. For a kit, also returns its computed stock and components.

`GET https://app.inventorymod.com/api/rpc/products/orderInfo?campaign_id=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Get a product

GET `products/get`

Get a product by id.

`GET https://app.inventorymod.com/api/rpc/products/get?campaign_id=1&id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| id | integer | **yes** |  |

Response:

```
{
  "data": {
    "id": 1,
    "campaignId": 1,
    "sku": "ABC-1",
    "barcode": "CODE",
    "name": "Sample",
    "manufacturerId": 1,
    "categoryId": 1,
    "price": 9.99,
    "priceOld": 9.99,
    "rrp": 9.99,
    "currencyId": 1,
    "purchaseCost": 9.99,
    "purchaseCostCurrencyId": 1,
    "url": "string",
    "imageUrl": "string",
    "minQty": 9.99,
    "customFieldValues": {},
    "isArchived": false,
    "kind": "simple",
    "laborCost": 9.99,
    "laborCostCurrencyId": 1,
    "componentsUpdatedAt": "2026-01-01T00:00:00.000Z",
    "parentId": 1,
    "variantKey": "string",
    "nameLocked": false,
    "createdAtUtc": "2026-01-01T00:00:00.000Z",
    "updatedAtUtc": "2026-01-01T00:00:00.000Z"
  }
}
```

### Find a product by SKU

GET `products/getBySku`

Find a product by SKU.

`GET https://app.inventorymod.com/api/rpc/products/getBySku?campaign_id=1&sku=ABC-1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| sku | string | **yes** |  |

Response:

```
{
  "data": {
    "id": 1,
    "campaignId": 1,
    "sku": "ABC-1",
    "barcode": "CODE",
    "name": "Sample",
    "manufacturerId": 1,
    "categoryId": 1,
    "price": 9.99,
    "priceOld": 9.99,
    "rrp": 9.99,
    "currencyId": 1,
    "purchaseCost": 9.99,
    "purchaseCostCurrencyId": 1,
    "url": "string",
    "imageUrl": "string",
    "minQty": 9.99,
    "customFieldValues": {},
    "isArchived": false,
    "kind": "simple",
    "laborCost": 9.99,
    "laborCostCurrencyId": 1,
    "componentsUpdatedAt": "2026-01-01T00:00:00.000Z",
    "parentId": 1,
    "variantKey": "string",
    "nameLocked": false,
    "createdAtUtc": "2026-01-01T00:00:00.000Z",
    "updatedAtUtc": "2026-01-01T00:00:00.000Z"
  }
}
```

### Find a product by SKU or barcode

GET `products/getByCode`

Find a product by SKU or barcode.

`GET https://app.inventorymod.com/api/rpc/products/getByCode?campaign_id=1&value=ABC-1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| value | string | **yes** |  |

Response:

```
{
  "data": {
    "id": 1,
    "campaignId": 1,
    "sku": "ABC-1",
    "barcode": "CODE",
    "name": "Sample",
    "manufacturerId": 1,
    "categoryId": 1,
    "price": 9.99,
    "priceOld": 9.99,
    "rrp": 9.99,
    "currencyId": 1,
    "purchaseCost": 9.99,
    "purchaseCostCurrencyId": 1,
    "url": "string",
    "imageUrl": "string",
    "minQty": 9.99,
    "customFieldValues": {},
    "isArchived": false,
    "kind": "simple",
    "laborCost": 9.99,
    "laborCostCurrencyId": 1,
    "componentsUpdatedAt": "2026-01-01T00:00:00.000Z",
    "parentId": 1,
    "variantKey": "string",
    "nameLocked": false,
    "createdAtUtc": "2026-01-01T00:00:00.000Z",
    "updatedAtUtc": "2026-01-01T00:00:00.000Z"
  }
}
```

### Get price history

GET `products/priceHistory`

Price history of a product.

`GET https://app.inventorymod.com/api/rpc/products/priceHistory?campaign_id=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "productId": 1,
      "price": 9.99,
      "currencyId": 1,
      "createdAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Create a product

POST `products/create`

Create a product. Returns its id.

`POST https://app.inventorymod.com/api/rpc/products/create?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "product": {
    "sku": "ABC-1",
    "barcode": "CODE",
    "name": "Sample",
    "manufacturerId": 1,
    "categoryId": 1,
    "price": 9.99,
    "priceOld": 9.99,
    "rrp": 9.99,
    "currencyId": 1,
    "purchaseCost": 9.99,
    "purchaseCostCurrencyId": 1,
    "url": "string",
    "imageUrl": "string",
    "minQty": 9.99,
    "customFieldValues": {},
    "isArchived": false,
    "kind": "simple",
    "laborCost": 9.99,
    "laborCostCurrencyId": 1
  }
}
```

Response:

```
{
  "data": 1
}
```

### Update a product

POST `products/update`

Update product fields. The kind field is ignored — use setProductKind.

`POST https://app.inventorymod.com/api/rpc/products/update?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Request body (JSON):

```
{
  "patch": {
    "sku": "ABC-1",
    "barcode": "CODE",
    "name": "Sample",
    "manufacturerId": 1,
    "categoryId": 1,
    "price": 9.99,
    "priceOld": 9.99,
    "rrp": 9.99,
    "currencyId": 1,
    "purchaseCost": 9.99,
    "purchaseCostCurrencyId": 1,
    "url": "string",
    "imageUrl": "string",
    "minQty": 9.99,
    "customFieldValues": {},
    "isArchived": false,
    "kind": "simple",
    "laborCost": 9.99,
    "laborCostCurrencyId": 1
  }
}
```

Response:

```
{
  "data": null
}
```

### Bulk update products

POST `products/bulkUpdate`

Apply the same changes to several products by id.

`POST https://app.inventorymod.com/api/rpc/products/bulkUpdate?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "ids": {},
  "patch": {}
}
```

Response:

```
{
  "data": null
}
```

### Create or update a product by SKU

POST `products/upsert`

Create a product, or update the existing one with the same SKU.

`POST https://app.inventorymod.com/api/rpc/products/upsert?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "product": {
    "sku": "ABC-1",
    "barcode": "CODE",
    "name": "Sample",
    "manufacturerId": 1,
    "categoryId": 1,
    "price": 9.99,
    "priceOld": 9.99,
    "rrp": 9.99,
    "currencyId": 1,
    "purchaseCost": 9.99,
    "purchaseCostCurrencyId": 1,
    "url": "string",
    "imageUrl": "string",
    "minQty": 9.99,
    "customFieldValues": {},
    "isArchived": false,
    "kind": "simple",
    "laborCost": 9.99,
    "laborCostCurrencyId": 1
  }
}
```

Response:

```
{
  "data": 1
}
```

### Get product references

GET `products/relations`

Count everything that references a product (movements, orders, reservations, stock) — useful before deleting it.

`GET https://app.inventorymod.com/api/rpc/products/relations?campaign_id=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Delete a product

POST `products/delete`

Delete a product. By default it fails if the product has movements, orders, reservations or stock — archive it instead. With cascade=true, all related records are deleted as well.

`POST https://app.inventorymod.com/api/rpc/products/delete?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Request body (JSON):

```
{
  "opts": {}
}
```

Response:

```
{
  "data": null
}
```

## Bill of materials

Components of assembled products and kits.

### List components

GET `components/list`

Components of a product. warehouseId selects the warehouse(s) for the “available” column; without it, stock is summed across all warehouses.

`GET https://app.inventorymod.com/api/rpc/components/list?campaign_id=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |
| warehouseId | integer | no |  |

Response:

```
{
  "data": []
}
```

### Add or update a component

POST `components/set`

Add a component or update its quantity. The quantity must be positive, the component must be a stocked product, cycles are rejected, and the parent must be an assembled product or a kit.

`POST https://app.inventorymod.com/api/rpc/components/set?campaign_id=1&productId=1&componentId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| productId | integer | **yes** |  |
| componentId | integer | **yes** |  |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Remove a component

POST `components/delete`

Remove a component from a product.

`POST https://app.inventorymod.com/api/rpc/components/delete?campaign_id=1&productId=1&componentId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| productId | integer | **yes** |  |
| componentId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Reorder components

POST `components/reorder`

Reorder components. componentIds must contain exactly the current set of component ids.

`POST https://app.inventorymod.com/api/rpc/components/reorder?campaign_id=1&productId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| productId | integer | **yes** |  |

Request body (JSON):

```
{
  "componentIds": {}
}
```

Response:

```
{
  "data": null
}
```

### Where a product is used

GET `components/whereUsed`

Products and kits that use this product as a component.

`GET https://app.inventorymod.com/api/rpc/components/whereUsed?campaign_id=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |

Response:

```
{
  "data": []
}
```

### Products not allowed as components

GET `components/forbidden`

Ids of products that cannot be added as components of productId (the product itself and its ancestors).

`GET https://app.inventorymod.com/api/rpc/components/forbidden?campaign_id=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Calculate assembly cost

GET `components/cost`

Unit cost of an assembled product from current component purchase prices, plus labour cost.

`GET https://app.inventorymod.com/api/rpc/components/cost?campaign_id=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

## Variant options

Option axes of a model, such as Size or Color.

### List option axes

GET `variantOptions/list`

Option axes of a model (e.g. Size, Color) with their values and the number of variants per value.

`GET https://app.inventorymod.com/api/rpc/variantOptions/list?campaign_id=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |

Response:

```
{
  "data": []
}
```

### Create an option axis

POST `variantOptions/create`

Add an option axis to a model. If the model already has variants, defaultValue is required.

`POST https://app.inventorymod.com/api/rpc/variantOptions/create?campaign_id=1&productId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| productId | integer | **yes** |  |

Request body (JSON):

```
{
  "name": {},
  "input": {}
}
```

Response:

```
{
  "data": {}
}
```

### Rename an option axis

POST `variantOptions/update`

Rename an option axis. Variant names are updated accordingly.

`POST https://app.inventorymod.com/api/rpc/variantOptions/update?campaign_id=1&optionId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| optionId | integer | **yes** |  |

Request body (JSON):

```
{
  "patch": {}
}
```

Response:

```
{
  "data": {}
}
```

### Delete an option axis

POST `variantOptions/delete`

Delete an option axis. Allowed when the model has no variants, or when variant combinations remain unique without it.

`POST https://app.inventorymod.com/api/rpc/variantOptions/delete?campaign_id=1&optionId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| optionId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Reorder option axes

POST `variantOptions/reorder`

Reorder option axes. This defines the order of values in variant names.

`POST https://app.inventorymod.com/api/rpc/variantOptions/reorder?campaign_id=1&productId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| productId | integer | **yes** |  |

Request body (JSON):

```
{
  "optionIds": {}
}
```

Response:

```
{
  "data": null
}
```

## Variant option values

Values of an option axis, such as S, M, L.

### Add an option value

POST `variantValues/create`

Add a value to an option axis. code is used in variant SKUs (transliterated from the value by default).

`POST https://app.inventorymod.com/api/rpc/variantValues/create?campaign_id=1&optionId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| optionId | integer | **yes** |  |

Request body (JSON):

```
{
  "value": {},
  "code": {}
}
```

Response:

```
{
  "data": 1
}
```

### Update an option value

POST `variantValues/update`

Change an option value or its code. Affected variant names are updated.

`POST https://app.inventorymod.com/api/rpc/variantValues/update?campaign_id=1&valueId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| valueId | integer | **yes** |  |

Request body (JSON):

```
{
  "patch": {}
}
```

Response:

```
{
  "data": {}
}
```

### Delete an option value

POST `variantValues/delete`

Delete an option value. Allowed only if no variant uses it.

`POST https://app.inventorymod.com/api/rpc/variantValues/delete?campaign_id=1&valueId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| valueId | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

### Reorder option values

POST `variantValues/reorder`

Reorder the values of an option axis.

`POST https://app.inventorymod.com/api/rpc/variantValues/reorder?campaign_id=1&optionId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| optionId | integer | **yes** |  |

Request body (JSON):

```
{
  "valueIds": {}
}
```

Response:

```
{
  "data": null
}
```

## Variants

Generate and manage the variants of a model.

### List variants

GET `variants/list`

Variants of one or more models, with their option values and stock.

`GET https://app.inventorymod.com/api/rpc/variants/list?campaign_id=1&parentIds=x`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| parentIds | string | **yes** |  |

Response:

```
{
  "data": []
}
```

### Generate variants

POST `variants/generate`

Generate variants for all combinations of option values. Fields are copied from the model, names and SKUs are built automatically (-2, -3 suffixes on collision). Existing combinations are skipped and reported.

`POST https://app.inventorymod.com/api/rpc/variants/generate?campaign_id=1&parentId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| parentId | integer | **yes** |  |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": {}
}
```

### Change variant option values

POST `variants/setValues`

Change the option values of an existing variant. The new combination must be unique.

`POST https://app.inventorymod.com/api/rpc/variants/setValues?campaign_id=1&variantId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| variantId | integer | **yes** |  |

Request body (JSON):

```
{
  "values": {}
}
```

Response:

```
{
  "data": {}
}
```

### Attach a product as a variant

POST `variants/attach`

Attach an existing product to a model as a variant. Its name is kept.

`POST https://app.inventorymod.com/api/rpc/variants/attach?campaign_id=1&parentId=1&productId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| parentId | integer | **yes** |  |
| productId | integer | **yes** |  |

Request body (JSON):

```
{
  "values": {}
}
```

Response:

```
{
  "data": {}
}
```

### Detach a variant

POST `variants/detach`

Detach a variant, turning it into a regular product. Its option values are removed, its name is kept.

`POST https://app.inventorymod.com/api/rpc/variants/detach?campaign_id=1&variantId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| variantId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Get the variant matrix

GET `variants/matrix`

Data for an option × option matrix, with stock for every warehouse in each cell.

`GET https://app.inventorymod.com/api/rpc/variants/matrix?campaign_id=1&parentId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| parentId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

## Product images

Image gallery of a product: links or uploaded files.

### List product images

GET `images/list`

Images of a product (metadata only, no bytes). The cover image comes first.

`GET https://app.inventorymod.com/api/rpc/images/list?campaign_id=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |

Response:

```
{
  "data": []
}
```

### Get image content

GET `images/getData`

Image content: for a URL image returns the link, for an uploaded image returns base64 data.

`GET https://app.inventorymod.com/api/rpc/images/getData?campaign_id=1&imageId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| imageId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Get cover images

POST `images/firstImages`

The cover image of each product in the list — for thumbnails.

`POST https://app.inventorymod.com/api/rpc/images/firstImages?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "productIds": {}
}
```

Response:

```
{
  "data": []
}
```

### Add an image

POST `images/add`

Add an image to the end of the gallery: either kind="url" with url, or kind="blob" with dataBase64 (and mimeType). The first image becomes the cover.

`POST https://app.inventorymod.com/api/rpc/images/add?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Delete an image

POST `images/delete`

Delete an image.

`POST https://app.inventorymod.com/api/rpc/images/delete?campaign_id=1&imageId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| imageId | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

### Reorder images

POST `images/reorder`

Reorder product images; the first id becomes the cover. Ids not listed are left unchanged.

`POST https://app.inventorymod.com/api/rpc/images/reorder?campaign_id=1&productId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| productId | integer | **yes** |  |

Request body (JSON):

```
{
  "orderedIds": {}
}
```

Response:

```
{
  "data": null
}
```

## Barcodes

Multiple barcodes per product, one of them primary.

### List barcodes

GET `barcodes/list`

All barcodes of a product, primary first.

`GET https://app.inventorymod.com/api/rpc/barcodes/list?campaign_id=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |

Response:

```
{
  "data": []
}
```

### Add a barcode

POST `barcodes/add`

Add a barcode. It is normalized and its type is detected automatically. The first barcode, or one added with isPrimary, becomes primary.

`POST https://app.inventorymod.com/api/rpc/barcodes/add?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Set the primary barcode

POST `barcodes/setPrimary`

Make a barcode the primary one.

`POST https://app.inventorymod.com/api/rpc/barcodes/setPrimary?campaign_id=1&barcodeId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| barcodeId | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

### Delete a barcode

POST `barcodes/delete`

Delete a barcode. If it was primary, the next remaining one becomes primary.

`POST https://app.inventorymod.com/api/rpc/barcodes/delete?campaign_id=1&barcodeId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| barcodeId | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

## Warehouses

Warehouses and stock locations.

### List warehouses

GET `warehouses/list`

List warehouses. Archived ones are included only with includeArchived.

`GET https://app.inventorymod.com/api/rpc/warehouses/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| includeArchived | boolean | no |  |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "name": "Sample",
      "code": "CODE",
      "type": "string",
      "address": "string",
      "contact": "string",
      "comment": "string",
      "capacity": 9.99,
      "isDefault": false,
      "isArchived": false,
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Create a warehouse

POST `warehouses/create`

Create a warehouse.

`POST https://app.inventorymod.com/api/rpc/warehouses/create?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "warehouse": {
    "name": "Sample",
    "code": "CODE",
    "type": "string",
    "address": "string",
    "contact": "string",
    "comment": "string",
    "capacity": 9.99,
    "isDefault": false,
    "isArchived": false
  }
}
```

Response:

```
{
  "data": 1
}
```

### Update a warehouse

POST `warehouses/update`

Update a warehouse. Its type can be changed, or it can be archived, only when it holds no stock, reservations or open orders.

`POST https://app.inventorymod.com/api/rpc/warehouses/update?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Request body (JSON):

```
{
  "data": {
    "name": "Sample",
    "code": "CODE",
    "type": "string",
    "address": "string",
    "contact": "string",
    "comment": "string",
    "capacity": 9.99,
    "isDefault": false,
    "isArchived": false
  }
}
```

Response:

```
{
  "data": null
}
```

### Delete a warehouse

POST `warehouses/delete`

Delete a warehouse. Not allowed if it holds stock, active reservations or open orders; a warehouse with history can only be archived.

`POST https://app.inventorymod.com/api/rpc/warehouses/delete?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

### Set the default warehouse

POST `warehouses/setDefault`

Set the default warehouse. It must be active and not a supplier warehouse.

`POST https://app.inventorymod.com/api/rpc/warehouses/setDefault?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

## Categories

Product categories.

### List categories

GET `categories/list`

List categories.

`GET https://app.inventorymod.com/api/rpc/categories/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "name": "Sample",
      "parentId": 1,
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Create a category

POST `categories/create`

Create a category.

`POST https://app.inventorymod.com/api/rpc/categories/create?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "category": {
    "name": "Sample",
    "parentId": 1
  }
}
```

Response:

```
{
  "data": 1
}
```

### Update a category

POST `categories/update`

Update a category.

`POST https://app.inventorymod.com/api/rpc/categories/update?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Request body (JSON):

```
{
  "data": {
    "name": "Sample",
    "parentId": 1
  }
}
```

Response:

```
{
  "data": null
}
```

### Delete a category

POST `categories/delete`

Delete a category.

`POST https://app.inventorymod.com/api/rpc/categories/delete?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

## Manufacturers

Product manufacturers and brands.

### List manufacturers

GET `manufacturers/list`

List manufacturers.

`GET https://app.inventorymod.com/api/rpc/manufacturers/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "name": "Sample",
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Create a manufacturer

POST `manufacturers/create`

Create a manufacturer.

`POST https://app.inventorymod.com/api/rpc/manufacturers/create?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "manufacturer": {
    "name": "Sample"
  }
}
```

Response:

```
{
  "data": 1
}
```

### Update a manufacturer

POST `manufacturers/update`

Update a manufacturer.

`POST https://app.inventorymod.com/api/rpc/manufacturers/update?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Request body (JSON):

```
{
  "data": {
    "name": "Sample"
  }
}
```

Response:

```
{
  "data": null
}
```

### Delete a manufacturer

POST `manufacturers/delete`

Delete a manufacturer.

`POST https://app.inventorymod.com/api/rpc/manufacturers/delete?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

## Currencies

Currencies and exchange rates to the base currency.

### List currencies

GET `currencies/list`

List currencies.

`GET https://app.inventorymod.com/api/rpc/currencies/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "name": "Sample",
      "rate": 9.99,
      "isDefault": false,
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Create a currency

POST `currencies/create`

Create a currency.

`POST https://app.inventorymod.com/api/rpc/currencies/create?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "currency": {
    "name": "Sample",
    "rate": 9.99,
    "isDefault": false
  }
}
```

Response:

```
{
  "data": 1
}
```

### Update a currency

POST `currencies/update`

Update a currency.

`POST https://app.inventorymod.com/api/rpc/currencies/update?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Request body (JSON):

```
{
  "data": {
    "name": "Sample",
    "rate": 9.99,
    "isDefault": false
  }
}
```

Response:

```
{
  "data": null
}
```

### Delete a currency

POST `currencies/delete`

Delete a currency.

`POST https://app.inventorymod.com/api/rpc/currencies/delete?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

### Set the base currency

POST `currencies/setDefault`

Set the base currency. All rates are relative to it, so they are recalculated: rate := rate / rate of the new base currency.

`POST https://app.inventorymod.com/api/rpc/currencies/setDefault?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

## Suppliers

Suppliers for purchase orders.

### List suppliers

GET `suppliers/list`

List suppliers.

`GET https://app.inventorymod.com/api/rpc/suppliers/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "name": "Sample",
      "code": "CODE",
      "contact": "string",
      "email": "user@example.com",
      "phone": "string",
      "address": "string",
      "comment": "string",
      "isArchived": false,
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Create a supplier

POST `suppliers/create`

Create a supplier.

`POST https://app.inventorymod.com/api/rpc/suppliers/create?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "supplier": {
    "name": "Sample",
    "code": "CODE",
    "contact": "string",
    "email": "user@example.com",
    "phone": "string",
    "address": "string",
    "comment": "string",
    "isArchived": false
  }
}
```

Response:

```
{
  "data": 1
}
```

### Update a supplier

POST `suppliers/update`

Update a supplier.

`POST https://app.inventorymod.com/api/rpc/suppliers/update?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Request body (JSON):

```
{
  "data": {
    "name": "Sample",
    "code": "CODE",
    "contact": "string",
    "email": "user@example.com",
    "phone": "string",
    "address": "string",
    "comment": "string",
    "isArchived": false
  }
}
```

Response:

```
{
  "data": null
}
```

### Delete a supplier

POST `suppliers/delete`

Delete a supplier. Suppliers with purchase orders can only be archived.

`POST https://app.inventorymod.com/api/rpc/suppliers/delete?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

## Customers

Customers for sales orders.

### List customers

GET `customers/list`

List customers.

`GET https://app.inventorymod.com/api/rpc/customers/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "name": "Sample",
      "code": "CODE",
      "contact": "string",
      "email": "user@example.com",
      "phone": "string",
      "address": "string",
      "comment": "string",
      "isArchived": false,
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Create a customer

POST `customers/create`

Create a customer.

`POST https://app.inventorymod.com/api/rpc/customers/create?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "customer": {
    "name": "Sample",
    "code": "CODE",
    "contact": "string",
    "email": "user@example.com",
    "phone": "string",
    "address": "string",
    "comment": "string",
    "isArchived": false
  }
}
```

Response:

```
{
  "data": 1
}
```

### Update a customer

POST `customers/update`

Update a customer.

`POST https://app.inventorymod.com/api/rpc/customers/update?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Request body (JSON):

```
{
  "data": {
    "name": "Sample",
    "code": "CODE",
    "contact": "string",
    "email": "user@example.com",
    "phone": "string",
    "address": "string",
    "comment": "string",
    "isArchived": false
  }
}
```

Response:

```
{
  "data": null
}
```

### Delete a customer

POST `customers/delete`

Delete a customer. Customers with orders can only be archived.

`POST https://app.inventorymod.com/api/rpc/customers/delete?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

## Custom fields

Your own product fields.

### List custom fields

GET `customFields/list`

List custom product fields.

`GET https://app.inventorymod.com/api/rpc/customFields/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "name": "Sample",
      "type": "string",
      "sortOrder": 1,
      "createdAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Create a custom field

POST `customFields/create`

Create a custom product field. Returns its id.

`POST https://app.inventorymod.com/api/rpc/customFields/create?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "data": {}
}
```

Response:

```
{
  "data": 1
}
```

### Update a custom field

POST `customFields/update`

Rename a custom field or change its type.

`POST https://app.inventorymod.com/api/rpc/customFields/update?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Request body (JSON):

```
{
  "data": {}
}
```

Response:

```
{
  "data": null
}
```

### Delete a custom field

POST `customFields/delete`

Delete a custom field.

`POST https://app.inventorymod.com/api/rpc/customFields/delete?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

## Stock operations

Receive, issue, adjust, transfer and reserve stock; stock counts and integrity checks.

### Receive stock

POST `stock/in`

Receive stock into a warehouse. Returns the operation id.

`POST https://app.inventorymod.com/api/rpc/stock/in?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Issue stock

POST `stock/out`

Issue stock from a warehouse.

`POST https://app.inventorymod.com/api/rpc/stock/out?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Adjust stock

POST `stock/adjust`

Set stock to the given quantity.

`POST https://app.inventorymod.com/api/rpc/stock/adjust?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Transfer stock

POST `stock/transfer`

Move stock between warehouses.

`POST https://app.inventorymod.com/api/rpc/stock/transfer?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Reserve stock

POST `stock/reserve`

Reserve stock.

`POST https://app.inventorymod.com/api/rpc/stock/reserve?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Reserve stock in bulk

POST `stock/reserveBulk`

Reserve stock in several warehouses in a single transaction: if any reservation fails, nothing is saved.

`POST https://app.inventorymod.com/api/rpc/stock/reserveBulk?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "inputs": {}
}
```

Response:

```
{
  "data": {}
}
```

### Release a reservation

POST `stock/unreserve`

Release a reservation.

`POST https://app.inventorymod.com/api/rpc/stock/unreserve?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Ship reserved stock

POST `stock/consumeReservation`

Ship reserved stock.

`POST https://app.inventorymod.com/api/rpc/stock/consumeReservation?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Receive a return

POST `stock/return`

Receive a customer return.

`POST https://app.inventorymod.com/api/rpc/stock/return?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Write off stock

POST `stock/writeOff`

Write off stock.

`POST https://app.inventorymod.com/api/rpc/stock/writeOff?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Run stock operations in bulk

POST `stock/bulk`

Run a batch of stock operations.

`POST https://app.inventorymod.com/api/rpc/stock/bulk?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Undo a movement

POST `stock/undoMovement`

Undo a single stock movement within the undo window. Assembly movements can only be undone as a whole operation; a movement can be undone once.

`POST https://app.inventorymod.com/api/rpc/stock/undoMovement?campaign_id=1&movementId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| movementId | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

### Check stock integrity

GET `stock/integrityCheck`

Report stock inconsistencies. Read-only.

`GET https://app.inventorymod.com/api/rpc/stock/integrityCheck?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": {}
}
```

### Repair stock integrity

POST `stock/integrityRepair`

Fix stock inconsistencies: recalculates reserved and available quantities. Physical stock is not changed; if the movement log disagrees with it, a corrective adjustment is recorded.

`POST https://app.inventorymod.com/api/rpc/stock/integrityRepair?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Response:

```
{
  "data": {}
}
```

### Reconcile stock with a file

POST `stock/reconcile`

Compare uploaded counts ({sku, warehouse, uploadedQty}) with current stock and return the differences. Warehouses match by name (case-insensitive) or id.

`POST https://app.inventorymod.com/api/rpc/stock/reconcile?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "rows": {}
}
```

Response:

```
{
  "data": {}
}
```

### Reconcile a stock count

POST `stock/countCheck`

Compare a stock count with current balances. Duplicate (SKU, warehouse) rows are summed; invalid quantities and archived or supplier warehouses are reported as row errors.

`POST https://app.inventorymod.com/api/rpc/stock/countCheck?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "rows": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Apply a stock count

POST `stock/countApply`

Apply a stock count across all warehouses in one transaction. A row is applied only if stock has not changed since reconciliation; otherwise it is returned in changed.

`POST https://app.inventorymod.com/api/rpc/stock/countApply?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": {}
}
```

## Assembly

Assemble and disassemble products from components.

### Assemble products

POST `assembly/assemble`

Assemble N units: consumes components and adds the finished product at its computed cost.

`POST https://app.inventorymod.com/api/rpc/assembly/assemble?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": {}
}
```

### Disassemble products

POST `assembly/disassemble`

Disassemble N units according to the current bill of materials, returning components to stock.

`POST https://app.inventorymod.com/api/rpc/assembly/disassemble?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": {}
}
```

### Undo an assembly

POST `assembly/undo`

Undo an entire assembly or disassembly operation within the undo window. A purchase price changed by the assembly is restored if it has not changed since.

`POST https://app.inventorymod.com/api/rpc/assembly/undo?campaign_id=1&operationId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| operationId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

### How many can be assembled

GET `assembly/buildable`

How many units can be assembled in a warehouse from the stock of direct components.

`GET https://app.inventorymod.com/api/rpc/assembly/buildable?campaign_id=1&productId=1&warehouseId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| productId | integer | **yes** |  |
| warehouseId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

## Stock balances

Quantity, reserved and available stock per warehouse.

### Get product stock

GET `balances/get`

Stock of a product in a warehouse: quantity, reserved and available.

`GET https://app.inventorymod.com/api/rpc/balances/get?campaign_id=1&warehouseId=1&productId=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| warehouseId | integer | **yes** |  |
| productId | integer | **yes** |  |

Response:

```
{
  "data": {
    "id": 1,
    "campaignId": 1,
    "warehouseId": 1,
    "productId": 1,
    "qty": 9.99,
    "reservedQty": 9.99,
    "availableQty": 9.99,
    "lastMovementAtUtc": "2026-01-01T00:00:00.000Z",
    "updatedAtUtc": "2026-01-01T00:00:00.000Z"
  }
}
```

### List stock balances

GET `balances/list`

Stock balances, optionally for one warehouse.

`GET https://app.inventorymod.com/api/rpc/balances/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| warehouseId | integer | no |  |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "warehouseId": 1,
      "productId": 1,
      "qty": 9.99,
      "reservedQty": 9.99,
      "availableQty": 9.99,
      "lastMovementAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Search stock balances

GET `balances/page`

Paginated stock balances with warehouse and status filters, search by name or SKU, and sorting.

`GET https://app.inventorymod.com/api/rpc/balances/page?campaign_id=1&limit=50&offset=0`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| warehouseId | integer | no |  |
| search | string | no |  |
| stockStatus | string all \| in \| out \| low | no |  |
| sortBy | string product \| warehouse \| qty \| reservedQty \| availableQty \| lastMovementAtUtc | no |  |
| sortOrder | string asc \| desc | no |  |
| limit | integer | **yes** |  |
| offset | integer | **yes** |  |
| parentId | integer | no |  |

Response:

```
{
  "data": {
    "items": [
      {
        "id": 1,
        "campaignId": 1,
        "warehouseId": 1,
        "productId": 1,
        "qty": 9.99,
        "reservedQty": 9.99,
        "availableQty": 9.99,
        "lastMovementAtUtc": "2026-01-01T00:00:00.000Z",
        "updatedAtUtc": "2026-01-01T00:00:00.000Z"
      }
    ],
    "totalCount": 1
  }
}
```

### Stock totals per warehouse

GET `balances/warehouseTotals`

Total physical stock per warehouse.

`GET https://app.inventorymod.com/api/rpc/balances/warehouseTotals?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": {}
}
```

### Kit availability

GET `balances/kits`

Paginated kits with their computed stock.

`GET https://app.inventorymod.com/api/rpc/balances/kits?campaign_id=1&limit=50&offset=0`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| warehouseId | integer | no |  |
| search | string | no |  |
| limit | integer | **yes** |  |
| offset | integer | **yes** |  |
| includeArchived | boolean | no |  |

Response:

```
{
  "data": {
    "items": [],
    "totalCount": 0
  }
}
```

## Stock movements

History of all stock movements.

### List movements

GET `movements/list`

Stock movements, with optional filters.

`GET https://app.inventorymod.com/api/rpc/movements/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| warehouseId | integer | no |  |
| productId | integer | no |  |
| movementType | string | no |  |
| startDate | string | no |  |
| endDate | string | no |  |
| operationId | integer | no |  |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "warehouseId": 1,
      "productId": 1,
      "sku": "ABC-1",
      "movementType": "string",
      "qtyDelta": 9.99,
      "reservedDelta": 9.99,
      "qtyBefore": 9.99,
      "qtyAfter": 9.99,
      "reservedBefore": 9.99,
      "reservedAfter": 9.99,
      "purchasePrice": 9.99,
      "purchaseCurrencyId": 1,
      "documentType": "string",
      "documentNumber": "string",
      "operationId": 1,
      "comment": "string",
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "createdBy": "string",
      "createdBySource": "string",
      "reversesMovementId": 1
    }
  ]
}
```

### Search movements

GET `movements/page`

Paginated stock movements.

`GET https://app.inventorymod.com/api/rpc/movements/page?campaign_id=1&limit=50&offset=0`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| warehouseId | integer | no |  |
| productId | integer | no |  |
| movementType | string | no |  |
| startDate | string | no |  |
| endDate | string | no |  |
| operationId | integer | no |  |
| search | string | no |  |
| sortBy | string createdAtUtc \| movementType \| product \| warehouse \| qtyDelta \| qtyAfter \| purchasePrice \| documentNumber | no |  |
| sortOrder | string asc \| desc | no |  |
| limit | integer | **yes** |  |
| offset | integer | **yes** |  |

Response:

```
{
  "data": {
    "items": [
      {
        "id": 1,
        "campaignId": 1,
        "warehouseId": 1,
        "productId": 1,
        "sku": "ABC-1",
        "movementType": "string",
        "qtyDelta": 9.99,
        "reservedDelta": 9.99,
        "qtyBefore": 9.99,
        "qtyAfter": 9.99,
        "reservedBefore": 9.99,
        "reservedAfter": 9.99,
        "purchasePrice": 9.99,
        "purchaseCurrencyId": 1,
        "documentType": "string",
        "documentNumber": "string",
        "operationId": 1,
        "comment": "string",
        "createdAtUtc": "2026-01-01T00:00:00.000Z",
        "createdBy": "string",
        "createdBySource": "string",
        "reversesMovementId": 1
      }
    ],
    "totalCount": 1
  }
}
```

## Reservations

Stock reserved for customers and orders.

### List reservations

GET `reservations/list`

Reservations, optionally filtered by status or date. Expired reservations are released first.

`GET https://app.inventorymod.com/api/rpc/reservations/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| status | string | no |  |
| startDate | string | no |  |
| endDate | string | no |  |
| warehouseId | integer | no |  |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "warehouseId": 1,
      "productId": 1,
      "qtyReserved": 9.99,
      "status": "Active",
      "reasonType": "string",
      "documentType": "string",
      "documentNumber": "string",
      "expiresAtUtc": "2026-01-01T00:00:00.000Z",
      "comment": "string",
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z",
      "releasedAtUtc": "2026-01-01T00:00:00.000Z",
      "orderItemId": 1
    }
  ]
}
```

### Search reservations

GET `reservations/page`

Paginated reservations with filters, search and sorting. Returns {items, totalCount}.

`GET https://app.inventorymod.com/api/rpc/reservations/page?campaign_id=1&limit=50&offset=0`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| status | string | no |  |
| warehouseId | integer | no |  |
| startDate | string | no |  |
| endDate | string | no |  |
| search | string | no |  |
| sortBy | string createdAtUtc \| product \| warehouse \| qtyReserved \| status \| expiresAtUtc \| documentNumber | no |  |
| sortOrder | string asc \| desc | no |  |
| limit | integer | **yes** |  |
| offset | integer | **yes** |  |

Response:

```
{
  "data": {
    "items": [
      {
        "id": 1,
        "campaignId": 1,
        "warehouseId": 1,
        "productId": 1,
        "qtyReserved": 9.99,
        "status": "Active",
        "reasonType": "string",
        "documentType": "string",
        "documentNumber": "string",
        "expiresAtUtc": "2026-01-01T00:00:00.000Z",
        "comment": "string",
        "createdAtUtc": "2026-01-01T00:00:00.000Z",
        "updatedAtUtc": "2026-01-01T00:00:00.000Z",
        "releasedAtUtc": "2026-01-01T00:00:00.000Z",
        "orderItemId": 1
      }
    ],
    "totalCount": 1
  }
}
```

## Sales orders

Customer orders: create, reserve, ship and cancel.

### List sales orders

GET `orders/list`

List sales orders.

`GET https://app.inventorymod.com/api/rpc/orders/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "orderNumber": "string",
      "customerId": 1,
      "source": "string",
      "status": "Active",
      "comment": "string",
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z",
      "cancelledAtUtc": "2026-01-01T00:00:00.000Z",
      "shippedAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Search sales orders

GET `orders/search`

Paginated sales orders.

`GET https://app.inventorymod.com/api/rpc/orders/search?campaign_id=1&limit=50&offset=0`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| search | string | no |  |
| status | string | no |  |
| limit | integer | **yes** |  |
| offset | integer | **yes** |  |

Response:

```
{
  "data": {
    "items": [
      {
        "id": 1,
        "campaignId": 1,
        "orderNumber": "string",
        "customerId": 1,
        "source": "string",
        "status": "Active",
        "comment": "string",
        "createdAtUtc": "2026-01-01T00:00:00.000Z",
        "updatedAtUtc": "2026-01-01T00:00:00.000Z",
        "cancelledAtUtc": "2026-01-01T00:00:00.000Z",
        "shippedAtUtc": "2026-01-01T00:00:00.000Z"
      }
    ],
    "totalCount": 1
  }
}
```

### Get a sales order

GET `orders/get`

Get a sales order with its lines.

`GET https://app.inventorymod.com/api/rpc/orders/get?campaign_id=1&id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| id | integer | **yes** |  |

Response:

```
{
  "data": {
    "id": 1,
    "campaignId": 1,
    "orderNumber": "string",
    "customerId": 1,
    "source": "string",
    "status": "Active",
    "comment": "string",
    "createdAtUtc": "2026-01-01T00:00:00.000Z",
    "updatedAtUtc": "2026-01-01T00:00:00.000Z",
    "cancelledAtUtc": "2026-01-01T00:00:00.000Z",
    "shippedAtUtc": "2026-01-01T00:00:00.000Z"
  }
}
```

### Create a sales order

POST `orders/create`

Create a sales order.

`POST https://app.inventorymod.com/api/rpc/orders/create?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Next order number

GET `orders/nextNumber`

Next free document number for a prefix (e.g. “ORD-20261006-”).

`GET https://app.inventorymod.com/api/rpc/orders/nextNumber?campaign_id=1&prefix=x`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| prefix | string | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Update a sales order

POST `orders/update`

Update a sales order (not shipped or cancelled). Lines are the full list: with id — existing, without id — new, omitted — deleted. Reservations are adjusted automatically.

`POST https://app.inventorymod.com/api/rpc/orders/update?campaign_id=1&orderId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| orderId | integer | **yes** |  |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": {}
}
```

### Reserve stock for an order

POST `orders/reserve`

Reserve stock for an order. Reserves what is available; a partial reservation sets the status to “Partially reserved”. Fails only if nothing could be reserved.

`POST https://app.inventorymod.com/api/rpc/orders/reserve?campaign_id=1&orderId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| orderId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Ship an order

POST `orders/ship`

Ship an order and deduct stock.

`POST https://app.inventorymod.com/api/rpc/orders/ship?campaign_id=1&orderId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| orderId | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

### Cancel an order

POST `orders/cancel`

Cancel an order and release its reservations atomically.

`POST https://app.inventorymod.com/api/rpc/orders/cancel?campaign_id=1&orderId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| orderId | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

## Purchase orders

Orders to suppliers: create, receive and cancel.

### List purchase orders

GET `purchaseOrders/list`

List purchase orders.

`GET https://app.inventorymod.com/api/rpc/purchaseOrders/list?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "orderNumber": "string",
      "supplierId": 1,
      "status": "Active",
      "expectedAtUtc": "2026-01-01T00:00:00.000Z",
      "comment": "string",
      "createdAtUtc": "2026-01-01T00:00:00.000Z",
      "updatedAtUtc": "2026-01-01T00:00:00.000Z",
      "cancelledAtUtc": "2026-01-01T00:00:00.000Z"
    }
  ]
}
```

### Search purchase orders

GET `purchaseOrders/search`

Paginated purchase orders with search by number and status filter.

`GET https://app.inventorymod.com/api/rpc/purchaseOrders/search?campaign_id=1&limit=50&offset=0`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| search | string | no |  |
| status | string | no |  |
| limit | integer | **yes** |  |
| offset | integer | **yes** |  |

Response:

```
{
  "data": {
    "items": [
      {
        "id": 1,
        "campaignId": 1,
        "orderNumber": "string",
        "supplierId": 1,
        "status": "Active",
        "expectedAtUtc": "2026-01-01T00:00:00.000Z",
        "comment": "string",
        "createdAtUtc": "2026-01-01T00:00:00.000Z",
        "updatedAtUtc": "2026-01-01T00:00:00.000Z",
        "cancelledAtUtc": "2026-01-01T00:00:00.000Z"
      }
    ],
    "totalCount": 1
  }
}
```

### Get a purchase order

GET `purchaseOrders/get`

Get a purchase order.

`GET https://app.inventorymod.com/api/rpc/purchaseOrders/get?campaign_id=1&id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| id | integer | **yes** |  |

Response:

```
{
  "data": {
    "id": 1,
    "campaignId": 1,
    "orderNumber": "string",
    "supplierId": 1,
    "status": "Active",
    "expectedAtUtc": "2026-01-01T00:00:00.000Z",
    "comment": "string",
    "createdAtUtc": "2026-01-01T00:00:00.000Z",
    "updatedAtUtc": "2026-01-01T00:00:00.000Z",
    "cancelledAtUtc": "2026-01-01T00:00:00.000Z"
  }
}
```

### Create a purchase order

POST `purchaseOrders/create`

Create a purchase order.

`POST https://app.inventorymod.com/api/rpc/purchaseOrders/create?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Next purchase order number

GET `purchaseOrders/nextNumber`

Next free purchase order number for a prefix (e.g. “PO-20261006-”).

`GET https://app.inventorymod.com/api/rpc/purchaseOrders/nextNumber?campaign_id=1&prefix=x`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| prefix | string | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Update a purchase order

POST `purchaseOrders/update`

Update a purchase order (not fully received or cancelled). Lines are the full list, as in updateOrder. Quantities cannot go below what was received; omitted prices keep their values.

`POST https://app.inventorymod.com/api/rpc/purchaseOrders/update?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": {}
}
```

### Receive a purchase order

POST `purchaseOrders/receive`

Receive goods against a purchase order.

`POST https://app.inventorymod.com/api/rpc/purchaseOrders/receive?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "input": {}
}
```

Response:

```
{
  "data": 1
}
```

### Cancel a purchase order

POST `purchaseOrders/cancel`

Cancel a purchase order.

`POST https://app.inventorymod.com/api/rpc/purchaseOrders/cancel?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Response:

```
{
  "data": null
}
```

## Reports

Inventory, sales and purchasing reports and the dashboard.

### Stock and margin summary

GET `reports/get`

Summary of stock, cost and margin.

`GET https://app.inventorymod.com/api/rpc/reports/get?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": {}
}
```

### Reports for a period

GET `reports/bundle`

Reports for a period: inventory, sales, purchasing, movements, ABC analysis and turnover, optionally per warehouse.

`GET https://app.inventorymod.com/api/rpc/reports/bundle?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| from | string | no |  |
| to | string | no |  |
| warehouseId | integer | no |  |

Response:

```
{
  "data": {}
}
```

### Dashboard summary

GET `reports/dashboard`

Dashboard summary: product count, stock value, out-of-stock and low-stock items, charts by category and warehouse.

`GET https://app.inventorymod.com/api/rpc/reports/dashboard?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": {}
}
```

## Settings

Workspace settings.

### Get settings

GET `settings/get`

Get workspace settings.

`GET https://app.inventorymod.com/api/rpc/settings/get?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": {
    "id": 1,
    "campaignId": 1,
    "locale": "string",
    "allowNegativeStock": false,
    "allowOverReservation": false,
    "defaultExportQuantityMode": "string",
    "dateFormat": "2026-01-01T00:00:00.000Z",
    "timeFormat": "string",
    "decimalSeparator": "string",
    "thousandsSeparator": "string",
    "lastWarehouseId": 1,
    "lastBackupReminderDate": "2026-01-01T00:00:00.000Z",
    "lastBackupAtUtc": "2026-01-01T00:00:00.000Z",
    "defaultBackupTarget": "string",
    "featureKits": false,
    "featureVariants": false,
    "featuresRolloutDone": false,
    "timeZone": "string"
  }
}
```

### Update settings

POST `settings/update`

Update workspace settings.

`POST https://app.inventorymod.com/api/rpc/settings/update?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "updates": {
    "locale": "string",
    "allowNegativeStock": false,
    "allowOverReservation": false,
    "defaultExportQuantityMode": "string",
    "dateFormat": "2026-01-01T00:00:00.000Z",
    "timeFormat": "string",
    "decimalSeparator": "string",
    "thousandsSeparator": "string",
    "lastWarehouseId": 1,
    "lastBackupReminderDate": "2026-01-01T00:00:00.000Z",
    "lastBackupAtUtc": "2026-01-01T00:00:00.000Z",
    "defaultBackupTarget": "string",
    "featureKits": false,
    "featureVariants": false,
    "featuresRolloutDone": false,
    "timeZone": "string"
  }
}
```

Response:

```
{
  "data": null
}
```

## Import

Bulk import of products, stock, documents and reference data.

### Import history

GET `imports/history`

History of import and export jobs.

`GET https://app.inventorymod.com/api/rpc/imports/history?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| updateMode | string | no |  |
| type | string IMPORT \| EXPORT | no |  |

Response:

```
{
  "data": [
    {
      "id": 1,
      "campaignId": 1,
      "type": "string",
      "fileName": "string",
      "fileType": "string",
      "format": "string",
      "profileId": 1,
      "updateMode": "2026-01-01T00:00:00.000Z",
      "stockImportMode": "string",
      "defaultWarehouseId": 1,
      "status": "Active",
      "rowsTotal": 1,
      "rowsProcessed": 1,
      "productsCreated": 1,
      "productsUpdated": 1,
      "categoriesCreated": 1,
      "manufacturersCreated": 1,
      "currenciesCreated": 1,
      "stockBalancesUpdated": 1,
      "rowsSkipped": 1,
      "errorsCount": 1,
      "warningsCount": 1,
      "messages": {},
      "startedAtUtc": "2026-01-01T00:00:00.000Z",
      "finishedAtUtc": "2026-01-01T00:00:00.000Z",
      "resultBlob": "string",
      "undoData": {}
    }
  ]
}
```

### Create an import job

POST `imports/createJob`

Create an import job.

`POST https://app.inventorymod.com/api/rpc/imports/createJob?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "job": {
    "type": "string",
    "fileName": "string",
    "fileType": "string",
    "format": "string",
    "profileId": 1,
    "updateMode": "2026-01-01T00:00:00.000Z",
    "stockImportMode": "string",
    "defaultWarehouseId": 1,
    "status": "Active",
    "rowsTotal": 1,
    "rowsProcessed": 1,
    "productsCreated": 1,
    "productsUpdated": 1,
    "categoriesCreated": 1,
    "manufacturersCreated": 1,
    "currenciesCreated": 1,
    "stockBalancesUpdated": 1,
    "rowsSkipped": 1,
    "errorsCount": 1,
    "warningsCount": 1,
    "messages": {},
    "startedAtUtc": "2026-01-01T00:00:00.000Z",
    "finishedAtUtc": "2026-01-01T00:00:00.000Z",
    "resultBlob": "string",
    "undoData": {}
  }
}
```

Response:

```
{
  "data": 1
}
```

### Update an import job

POST `imports/updateJob`

Update an import job.

`POST https://app.inventorymod.com/api/rpc/imports/updateJob?campaign_id=1&id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| id | integer | **yes** |  |

Request body (JSON):

```
{
  "updates": {
    "type": "string",
    "fileName": "string",
    "fileType": "string",
    "format": "string",
    "profileId": 1,
    "updateMode": "2026-01-01T00:00:00.000Z",
    "stockImportMode": "string",
    "defaultWarehouseId": 1,
    "status": "Active",
    "rowsTotal": 1,
    "rowsProcessed": 1,
    "productsCreated": 1,
    "productsUpdated": 1,
    "categoriesCreated": 1,
    "manufacturersCreated": 1,
    "currenciesCreated": 1,
    "stockBalancesUpdated": 1,
    "rowsSkipped": 1,
    "errorsCount": 1,
    "warningsCount": 1,
    "messages": {},
    "startedAtUtc": "2026-01-01T00:00:00.000Z",
    "finishedAtUtc": "2026-01-01T00:00:00.000Z",
    "resultBlob": "string",
    "undoData": {}
  }
}
```

Response:

```
{
  "data": null
}
```

### Undo an import

POST `imports/undo`

Undo an import by deleting the records it created. Returns the number of deleted records.

`POST https://app.inventorymod.com/api/rpc/imports/undo?campaign_id=1&jobId=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| jobId | integer | **yes** |  |

Response:

```
{
  "data": {}
}
```

### Import products

POST `imports/execProducts`

Import products: mapped fields, references by name (optionally created), kinds and variants.

`POST https://app.inventorymod.com/api/rpc/imports/execProducts?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import stock

POST `imports/execStock`

Import stock or movements by SKU. Unknown SKUs are reported, or created with createMissingProducts.

`POST https://app.inventorymod.com/api/rpc/imports/execStock?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import customers

POST `imports/execCustomers`

Import customers.

`POST https://app.inventorymod.com/api/rpc/imports/execCustomers?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import suppliers

POST `imports/execSuppliers`

Import suppliers.

`POST https://app.inventorymod.com/api/rpc/imports/execSuppliers?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import categories

POST `imports/execCategories`

Import categories; hierarchy is written as “Parent -> Child”.

`POST https://app.inventorymod.com/api/rpc/imports/execCategories?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import manufacturers

POST `imports/execManufacturers`

Import manufacturers.

`POST https://app.inventorymod.com/api/rpc/imports/execManufacturers?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import warehouses

POST `imports/execWarehouses`

Import warehouses.

`POST https://app.inventorymod.com/api/rpc/imports/execWarehouses?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import currencies

POST `imports/execCurrencies`

Import currencies.

`POST https://app.inventorymod.com/api/rpc/imports/execCurrencies?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import sales orders

POST `imports/execOrders`

Import sales orders; rows are grouped by order number.

`POST https://app.inventorymod.com/api/rpc/imports/execOrders?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import purchase orders

POST `imports/execPurchaseOrders`

Import purchase orders; rows are grouped by order number.

`POST https://app.inventorymod.com/api/rpc/imports/execPurchaseOrders?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import movements

POST `imports/execMovements`

Import movements: qty > 0 receives, qty < 0 issues; with a target warehouse the row becomes a transfer.

`POST https://app.inventorymod.com/api/rpc/imports/execMovements?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import reservations

POST `imports/execReservations`

Import reservations: one reservation per row.

`POST https://app.inventorymod.com/api/rpc/imports/execReservations?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

### Import bills of materials

POST `imports/execComponents`

Import bills of materials: “product SKU, component SKU, quantity”. Replaces existing components and sets the product kind to assembled.

`POST https://app.inventorymod.com/api/rpc/imports/execComponents?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Request body (JSON):

```
{
  "items": {},
  "opts": {}
}
```

Response:

```
{
  "data": {}
}
```

## Maintenance

Data cleanup operations.

### Delete all data

POST `backup/wipeAll`

Delete ALL workspace data (products, stock, documents, reference data, import history). Settings are kept. Returns the number of cleared tables.

`POST https://app.inventorymod.com/api/rpc/backup/wipeAll?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Response:

```
{
  "data": {}
}
```

### Clean up orphaned stock records

POST `backup/cleanupOrphans`

Delete stock records that reference deleted products. Returns the number of deleted rows per table.

`POST https://app.inventorymod.com/api/rpc/backup/cleanupOrphans?campaign_id=1`

Write access: a key with the `write` scope in the `Authorization: Bearer <key>` header.

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |

Response:

```
{
  "data": {}
}
```

## Activity log

Who did what and when.

### List activity

GET `activity/list`

Activity log, newest first. search matches the description and method name.

`GET https://app.inventorymod.com/api/rpc/activity/list?campaign_id=1&limit=50&offset=0`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |
| limit | integer | **yes** |  |
| offset | integer | **yes** |  |
| module | string | no |  |
| search | string | no |  |

Response:

```
{
  "data": {}
}
```

### Activity summary

GET `activity/summary`

Activity summary. userId limits it to one user.

`GET https://app.inventorymod.com/api/rpc/activity/summary?campaign_id=1`

| Parameter (query) | Type | Required |  |
| --- | --- | --- | --- |
| campaign_id | integer | **yes** | workspace of the API key |
| api_key | string | no | for reads from a browser; writes use the Authorization header |

Response:

```
{
  "data": {}
}
```
