Skip to main content

Inventory API

The Inventory API provides endpoints for viewing inventory levels, analytics, channel-location ATP matrices, and managing cycle counts.
Scope: Tenant-scoped; requires authenticated org context
Availability: Not available in SuperAdmin

Authentication

All requests require authentication. Include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
See Authentication for details.

Base URL

https://app.betterdata.co/api/inventory

Headers

All requests must include:
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY

Endpoints

MethodPathSummaryAuthStabilityPermissions
GET/api/inventoryList inventory itemssessionstableinventory.read
POST/api/inventory/adjustAdjust inventorysessionstableinventory.adjust
GET/api/inventory/adjustmentsList inventory adjustmentssessionstableinventory.adjust
POST/api/inventory/adjustmentsCreate inventory adjustmentsessionstableinventory.adjust
POST/api/inventory/adjustments/lot-correctionCreate lot correction adjustmentsessionstableinventory.adjust
GET/api/inventory/adjustments/reason-codesList adjustment reason codessessionstableinventory.adjust
GET/api/inventory/adjustments/record-stockList recorded stock adjustmentssessionstableinventory.adjust
POST/api/inventory/adjustments/record-stockRecord stock adjustmentsessionstableinventory.adjust
GET/api/inventory/availabilityList availability recordssessionstableinventory.read
GET/api/inventory/availability/[id]Get availability recordsessionstableinventory.read
POST/api/inventory/availability/[id]Create availability recordsessionstableinventory.write
POST/api/inventory/availability/checkCheck availabilitysessionstableinventory.read
GET/api/inventory/channel-locationGet channel × location ATP matrixsessionstableinventory.read
GET/api/inventory/channel-location/drilldownDrill down into channel-location ATPsessionstableinventory.read
GET/api/inventory/channel/summaryGet channel inventory summarysessionstableinventory.read
GET/api/inventory/cycle-countList cycle count batchessessionstableinventory.cyclecount
POST/api/inventory/cycle-countCreate cycle count batchsessionstableinventory.cyclecount
GET/api/inventory/cycle-count/[batchId]Get cycle count batch detailssessionstableinventory.cyclecount
POST/api/inventory/cycle-count/[batchId]Update cycle count batchsessionstableinventory.cyclecount
GET/api/inventory/cycle-count/abcGet ABC classification for cycle countingsessionstableinventory.cyclecount
POST/api/inventory/cycle-count/abcCreate ABC-based cycle countsessionstableinventory.cyclecount
GET/api/inventory/cycle-count/blind-formGet blind cycle count formsessionstableinventory.cyclecount
POST/api/inventory/cycle-count/resolveResolve cycle count discrepanciessessionstableinventory.cyclecount
GET/api/inventory/expiredList expired inventorysessionstableinventory.read
POST/api/inventory/expired/mark-consumedMark expired inventory as consumedsessionstableinventory.write
POST/api/inventory/expired/mark-expiredMark inventory as expiredsessionstableinventory.write
POST/api/inventory/expired/transfer-destructionTransfer expired inventory for destructionsessionstableinventory.write
GET/api/inventory/holdsList inventory holdssessionstableinventory.read
POST/api/inventory/holdsCreate inventory holdsessionstableinventory.write
POST/api/inventory/holds/releaseRelease inventory holdsessionstableinventory.write
GET/api/inventory/locationsList inventory by locationsessionstableinventory.read
GET/api/inventory/lot-control/validateGet lot control validationsessionstableinventory.read
POST/api/inventory/lot-control/validateValidate lot controlsessionstableinventory.read
GET/api/inventory/put-awayList put-away taskssessionstableinventory.read
POST/api/inventory/put-awayCreate put-away tasksessionstableinventory.write
POST/api/inventory/record-stockRecord stocksessionstableinventory.write
GET/api/inventory/replenishmentList replenishment recordssessionstablereplenishment.read
POST/api/inventory/replenishmentCreate replenishment recordsessionstablereplenishment.write
GET/api/inventory/replenishment/configGet replenishment configurationsessionstablereplenishment.read
POST/api/inventory/replenishment/configUpdate replenishment configurationsessionstablereplenishment.write
POST/api/inventory/replenishment/suggestionsGet replenishment suggestionssessionstablereplenishment.read
GET/api/inventory/transfersList inventory transferssessionstabletransfers.read
POST/api/inventory/transfersCreate inventory transfersessionstabletransfers.write
GET/api/inventory/transfers/[id]Get inventory transfersessionstabletransfers.read
POST/api/inventory/transfers/[id]Update inventory transfersessionstabletransfers.write
GET/api/inventory/transfers/binsGet transfer binssessionstabletransfers.read
GET/api/products/[id]/inventory-levelsGet product inventory levelssessionstableproducts.read, inventory.read
GET/api/stock-requestsList stock requestssessionstablestockrequests.read
POST/api/stock-requestsCreate a stock requestsessionstablestockrequests.write
GET/api/stock-requests/[id]Get a specific stock requestsessionstablestockrequests.read
PATCH/api/stock-requests/[id]Update a stock requestsessionstablestockrequests.write
DELETE/api/stock-requests/[id]Delete a stock requestsessionstablestockrequests.write
POST/api/stock-requests/[id]/approveApprove a stock requestsessionstablestockrequests.approve
POST/api/stock-requests/[id]/commentAdd comment to stock requestsessionstablestockrequests.write
GET/api/stock-requests/[id]/linesGet stock request linessessionstablestockrequests.read
POST/api/stock-requests/[id]/linesAdd line to stock requestsessionstablestockrequests.write
POST/api/stock-requests/[id]/rejectReject a stock requestsessionstablestockrequests.approve
POST/api/stock-requests/[id]/rollbackRollback a stock requestsessionstablestockrequests.write
GET/api/stock-requests/[id]/statusGet stock request statussessionstablestockrequests.read
POST/api/stock-requests/[id]/statusUpdate stock request statussessionstablestockrequests.write
POST/api/stock-requests/[id]/submitSubmit a stock requestsessionstablestockrequests.write
GET/api/stock-requests/by-categoryGet stock requests by categorysessionstablestockrequests.read
GET/api/stock-requests/dashboardGet stock requests dashboard datasessionstablestockrequests.read
GET/api/stock-requests/filtersGet stock request filter optionssessionstablestockrequests.read
GET/api/stock-requests/pending-approvalsGet pending approvalssessionstablestockrequests.approve
GET/api/stock-requests/products/searchSearch products for stock requestssessionstablestockrequests.read, products.read
GET/api/stock-requests/products/stocklistGet stocklist for stock requestssessionstablestockrequests.read
| GET | /cycle-count | List cycle count batches | | POST | /cycle-count | Create cycle count batch | | GET | /cycle-count/[batchId] | Get cycle count batch details | | POST | /cycle-count/resolve | Resolve cycle count discrepancies |

Example Requests

Get Channel × Location ATP Matrix

curl -X GET "https://app.betterdata.co/api/inventory/channel-location?locationId=loc_123&page=1&limit=50" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Response:
{
  "products": [
    {
      "productMasterId": "prod_123",
      "productName": "Product Name",
      "globalSku": "SKU-123",
      "categoryName": "Category",
      "channels": [
        {
          "channelId": "DTC",
          "channelName": "Direct to Consumer",
          "atp": 150,
          "onHand": 200,
          "reserved": 50,
          "available": 150,
          "severity": "OK",
          "threshold": 10,
          "policyId": "policy_123"
        }
      ],
      "totalOnHand": 200,
      "totalReserved": 50,
      "minAtp": 150,
      "maxAtp": 150,
      "hasCritical": false
    }
  ],
  "channels": [
    {
      "channelId": "DTC",
      "channelName": "Direct to Consumer",
      "channelType": "E_COMMERCE",
      "policyId": "policy_123",
      "lowAtpThreshold": 10
    }
  ],
  "location": {
    "id": "loc_123",
    "name": "Main Warehouse"
  },
  "pagination": {
    "page": 1,
    "pageSize": 50,
    "total": 150,
    "totalPages": 3
  }
}

List Inventory Items

curl -X GET "https://app.betterdata.co/api/inventory?locationId=loc_123&productMasterId=prod_123" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Response:
{
  "items": [
    {
      "id": "item_123",
      "productMasterId": "prod_123",
      "locationId": "loc_123",
      "quantityOnHand": 200,
      "quantityReserved": 50,
      "quantityAvailable": 150,
      "lotId": "lot_123",
      "expiryDate": "2024-12-31",
      "binId": "bin_123"
    }
  ],
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "total": 1,
    "totalPages": 1
  }
}

Get Inventory Analytics

curl -X GET "https://app.betterdata.co/api/inventory/analytics?locationId=loc_123&fromDate=2024-01-01&toDate=2024-12-31" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Response:
{
  "analytics": {
    "totalValue": 50000.00,
    "totalUnits": 1000,
    "turnoverRate": 12.5,
    "averageDaysOnHand": 30,
    "slowMovingItems": 25,
    "expiringItems": 10,
    "byCategory": [
      {
        "categoryId": "cat_123",
        "categoryName": "Category",
        "value": 25000.00,
        "units": 500
      }
    ]
  },
  "period": {
    "from": "2024-01-01T00:00:00Z",
    "to": "2024-12-31T23:59:59Z"
  }
}

Common Errors

401 Unauthorized

{
  "error": "Unauthorized"
}
Cause: Missing or invalid API key. Solution: Include a valid API key in the Authorization header.

400 Bad Request

{
  "error": "locationId is required"
}
Cause: Required query parameter missing. Solution: Include all required query parameters in the request.

404 Not Found

{
  "error": "Location not found or not accessible"
}
Cause: Location doesn’t exist or isn’t accessible to your organization. Solution: Verify the location ID and ensure you have access to it.

500 Internal Server Error

{
  "error": "Internal Server Error",
  "message": "ATP calculation failed"
}
Cause: Server error during ATP calculation or data retrieval. Solution: Retry the request. If the error persists, contact support.

Query Parameters

Channel-Location ATP

  • locationId (required): Location ID
  • search: Search by product name or SKU
  • channels: Comma-separated channel IDs to filter
  • page: Page number (default: 1)
  • limit: Page size (default: 50, max: 200)

List Inventory

  • locationId: Filter by location
  • productMasterId: Filter by product
  • lotId: Filter by lot
  • binId: Filter by bin
  • page: Page number (default: 1)
  • limit: Page size (default: 20, max: 100)

Inventory Analytics

  • locationId: Filter by location
  • fromDate: Start date (ISO string)
  • toDate: End date (ISO string)
  • categoryId: Filter by category

Request/Response Schemas

Channel ATP Cell

{
  channelId: string;
  channelName: string;
  atp: number;
  onHand: number;
  reserved: number;
  available: number;
  severity: "OK" | "LOW" | "CRITICAL";
  threshold?: number;
  policyId?: string;
}

Inventory Item

{
  id: string;
  productMasterId: string;
  locationId: string;
  quantityOnHand: number;
  quantityReserved: number;
  quantityAvailable: number;
  lotId?: string;
  expiryDate?: string; // ISO date
  binId?: string;
  createdAt: string; // ISO datetime
  updatedAt: string; // ISO datetime
}

Inventory Analytics

{
  totalValue: number;
  totalUnits: number;
  turnoverRate: number;
  averageDaysOnHand: number;
  slowMovingItems: number;
  expiringItems: number;
  byCategory: Array<{
    categoryId: string;
    categoryName: string;
    value: number;
    units: number;
  }>;
}


Permissions & Roles

Inventory API access requires inventory.read permission. Some endpoints may require additional permissions (e.g., inventory.cyclecount for cycle count endpoints).