Developer overview
API reference15 minute readAPI v1

Inventory sync API

Read stock, push absolute SKU quantities, audit movements and build retry-safe ERP inventory synchronisation.

Browse developer docs

The Inventory API lets external systems read product stock levels, push stock updates, and view stock movement history. Use it to keep SalesPro Hub in sync with your warehouse or ERP system.

Endpoints

List Products

text
GET /api/v1/inventory

Permission required: inventory:read

Retrieve a deterministic, paginated list of tenant products with their current stock levels. Results are ordered by SKU and then internal ID.

Query Parameters

ParameterTypeDescription
is_activebooleanOptional active/inactive filter
updated_sinceISO 8601Only products updated at or after this timestamp
per_pageintegerResults per page (1-100, default 100)
pageintegerPage number (minimum 1)

Example

bash
curl -X GET "https://portal.salesrepsoftware.co.za/api/v1/inventory" \
  -H "X-API-Key: sk_your_key" \
  -H "Accept: application/json"

Response

json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "sku": "WDG-001",
      "name": "Widget A",
      "stock_qty": 150,
      "reserved_qty": 20,
      "available_qty": 130,
      "reservation_shortfall_qty": 0,
      "low_stock_threshold": 25,
      "is_low_stock": false,
      "is_out_of_stock": false,
      "is_active": true
    },
    {
      "id": 2,
      "sku": "WDG-002",
      "name": "Widget B",
      "stock_qty": 8,
      "reserved_qty": 3,
      "available_qty": 5,
      "reservation_shortfall_qty": 0,
      "low_stock_threshold": 10,
      "is_low_stock": true,
      "is_out_of_stock": false,
      "is_active": true
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 100,
    "total": 2,
    "synced_at": "2026-02-09T12:00:00+02:00"
  }
}

Stock Quantity Fields

FieldDescription
stock_qtyTotal physical stock on hand
reserved_qtyQuantity reserved by pending/confirmed orders
available_qtyStock available to sell (stock_qty - reserved_qty)
reservation_shortfall_qtyReserved demand above physical on-hand stock; zero when reservations are fully covered
low_stock_thresholdAlert threshold configured per product
is_low_stocktrue when stock_qty <= low_stock_threshold and stock_qty > 0
is_out_of_stocktrue when stock_qty <= 0

Get Single Product

text
GET /api/v1/inventory/{sku}

Permission required: inventory:read

Look up a single product by its SKU.

Example

bash
curl -X GET "https://portal.salesrepsoftware.co.za/api/v1/inventory/WDG-001" \
  -H "X-API-Key: sk_your_key" \
  -H "Accept: application/json"

Response

json
{
  "success": true,
  "data": {
    "id": 1,
    "sku": "WDG-001",
    "name": "Widget A",
    "stock_qty": 150,
    "reserved_qty": 20,
    "available_qty": 130,
    "reservation_shortfall_qty": 0,
    "low_stock_threshold": 25,
    "is_low_stock": false,
    "is_out_of_stock": false,
    "is_active": true
  }
}

Update Stock for Single Product

text
PUT /api/v1/inventory/{sku}

Permission required: inventory:write

Set the stock quantity for a single product. This performs an absolute update (sets the stock to the given value, not a relative adjustment).

Request Body

FieldTypeRequiredDescription
stock_qtyintegerYesNew stock quantity (minimum 0)
referencestringNoIdempotency reference for this update (e.g., ERP event ID). Max 255 characters.

Example

bash
curl -X PUT "https://portal.salesrepsoftware.co.za/api/v1/inventory/WDG-001" \
  -H "X-API-Key: sk_your_key" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"stock_qty": 200, "reference": "WH-RECEIPT-1234"}'

Response

json
{
  "success": true,
  "data": {
    "sku": "WDG-001",
    "name": "Widget A",
    "stock_qty": 200,
    "reserved_qty": 20,
    "available_qty": 180,
    "reservation_shortfall_qty": 0,
    "changed": true,
    "replayed": false
  },
  "message": "Stock updated successfully"
}

What Happens on Update

  1. The product row is locked so concurrent order and ERP writes cannot calculate from stale stock.
  2. A stock movement record is created with type sync for the audit trail.
  3. A non-empty reference acts as an idempotency key for that SKU. Replaying the same reference and quantity returns the current stock without overwriting a newer update.
  4. Reusing the reference for a different quantity returns HTTP 409 with code inventory_reference_conflict.
  5. A changed stock level emits StockLevelChanged only after the database transaction commits.

An authoritative ERP snapshot may be lower than SalesPro Hub's existing reservations. SalesPro Hub keeps the physical quantity accurate, returns reservation_shortfall_qty, blocks a delivery deduction that would make stock negative, and requires the shortage to be reconciled.


Bulk Update Stock

text
POST /api/v1/inventory/bulk

Permission required: inventory:write

Update stock for multiple products in a single request. Efficient for daily warehouse syncs.

Request Body

FieldTypeRequiredDescription
productsarrayYesArray of products to update (1-500 items)
products[].skustringYesProduct SKU; each SKU may appear only once per request
products[].stock_qtyintegerYesNew stock quantity (minimum 0)
referencestringNoIdempotency reference applied independently to each SKU. Max 255 characters.

Example

bash
curl -X POST "https://portal.salesrepsoftware.co.za/api/v1/inventory/bulk" \
  -H "X-API-Key: sk_your_key" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "products": [
      {"sku": "WDG-001", "stock_qty": 200},
      {"sku": "WDG-002", "stock_qty": 50},
      {"sku": "WDG-003", "stock_qty": 0},
      {"sku": "INVALID-SKU", "stock_qty": 10}
    ],
    "reference": "DAILY-SYNC-20260209"
  }'

Response

json
{
  "success": true,
  "data": {
    "updated": 3,
    "replayed": 0,
    "failed": 1,
    "errors": [
      "SKU 'INVALID-SKU' not found"
    ]
  },
  "message": "Updated 3 products, 1 failed"
}

The bulk endpoint processes all valid products even if some fail. Check replayed and the errors array; a partial failure is still returned with HTTP 200 so the connector can reconcile each SKU.


Get Stock Movement History

text
GET /api/v1/inventory/movements

Permission required: inventory:read

View the audit trail of all stock changes. Useful for reconciliation and debugging stock discrepancies.

Query Parameters

ParameterTypeDescription
skustringFilter by product SKU
typestringFilter by movement type (see table below)
from_datedateMovements created on or after this date
to_datedateMovements created on or before this date
per_pageintegerResults per page (1-100, default 50)

Movement Types

TypeDescription
reservationStock reserved when order submitted
deductionStock deducted when order delivered
releaseReserved stock released when order cancelled
adjustmentManual stock adjustment by admin
syncStock updated via API
importStock set during CSV/bulk import

Example

bash
curl -X GET "https://portal.salesrepsoftware.co.za/api/v1/inventory/movements?sku=WDG-001&type=sync&per_page=10" \
  -H "X-API-Key: sk_your_key" \
  -H "Accept: application/json"

Response

json
{
  "success": true,
  "data": [
    {
      "id": 456,
      "product": {
        "id": 1,
        "sku": "WDG-001",
        "name": "Widget A"
      },
      "order": null,
      "type": "sync",
      "quantity": 50,
      "stock_before": 150,
      "stock_after": 200,
      "reserved_before": 20,
      "reserved_after": 20,
      "reference": "DAILY-SYNC-20260209",
      "notes": "Stock synced from external system",
      "created_at": "2026-02-09T06:00:00+02:00"
    }
  ],
  "meta": {
    "current_page": 1,
    "last_page": 1,
    "per_page": 10,
    "total": 1
  }
}

Daily Full Sync

Run once daily (e.g., 6:00 AM before business hours):

bash
# Export all stock levels from your warehouse system, then:
curl -X POST "https://portal.salesrepsoftware.co.za/api/v1/inventory/bulk" \
  -H "X-API-Key: sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{
    "products": [
      {"sku": "WDG-001", "stock_qty": 200},
      {"sku": "WDG-002", "stock_qty": 50}
    ],
    "reference": "DAILY-SYNC-20260209"
  }'

Real-Time Updates

For systems that need tighter sync, update individual products as stock changes:

bash
curl -X PUT "https://portal.salesrepsoftware.co.za/api/v1/inventory/WDG-001" \
  -H "X-API-Key: sk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"stock_qty": 195, "reference": "WH-PICK-789"}'

Bi-Directional Sync

Depending on the tenant's configured inventory policy, SalesPro Hub can also change stock levels when:

  • Orders are submitted — stock is reserved or deducted
  • Orders are delivered — reserved stock is deducted
  • Orders are cancelled — reserved stock is released
  • Admins adjust stock — manual corrections

To capture these changes in your external system, use webhooks with the inventory.* events, or poll the movements endpoint:

bash
curl -X GET "https://portal.salesrepsoftware.co.za/api/v1/inventory/movements?from_date=2026-02-09&type=deduction" \
  -H "X-API-Key: sk_your_key"

Choose one physical-stock system of record. Do not deduct the same delivery in both the ERP and SalesPro Hub.

Build against the real API

Professional API features are included in the 14-day trial.