R
RouteIQ
Make every order your best decision
RouteIQ API Docs

Route warehouse decisions through your own systems.

Use RouteIQ’s API to create secure keys, validate access, sync inventory, route one order in real time, or route a moderate batch of orders in one request.

Use the RouteIQ Customer API to sync inventory, route orders, review routing responses, and access supported report exports. For CSV report endpoint details and report field definitions, see the Report Export API.

Quick Start

1. Create an API key

Create a test or live API key from Account → API Access.

Test keys write to your test environment. Live keys write to your live environment and count toward routed-order usage.

2. Set your base URL

Production:

https://gorouteiq.com

Sandbox:

Use the sandbox host provided by RouteIQ.

3. Send your API key

Include your key in the Authorization header with each request.

Authorization: Bearer riq_test_YOUR_API_KEY

4. Validate the key

GET /api/v1/me

5. Sync inventory

POST /api/v1/inventory

6. Route orders

Single order:

POST /api/v1/orders/route

Batch orders:

POST /api/v1/orders/batch-route
Inventory must be synced before routing orders. Warehouse IDs in your API payload must match enabled warehouse IDs configured in RouteIQ.

Recommended integration flows

Most integrations use one of these patterns. RouteIQ can run as an inventory-aware routing engine or as a routing-only recommendation engine depending on the client’s routing control settings.

Real-time routing

1Sync inventory when enabled

If Use Inventory Availability is enabled, send current available quantity with POST /api/v1/inventory.

2Route each order

Call POST /api/v1/orders/route as each order is ready. RouteIQ creates a routing run, writes the API order into canonical order history, and returns one order result in results[].

3Use the decision

Create downstream shipment or work records from shipments[]. Each shipment includes a selected_warehouse and the SKU quantities to ship from that warehouse.

Wave or batch routing

1Prepare orders

Send up to 5,000 orders in one synchronous request. For larger scheduled bulk files, contact RouteIQ for async or managed batch processing options.

2Route the batch

Call POST /api/v1/orders/batch-route. RouteIQ creates one routing run, writes the API orders into canonical order history, and returns one result per order.

3Apply the results

Loop through each order result’s shipments[]. A full route returns one shipment; a split route returns multiple shipments.

Authentication

Customer API endpoints use API-key authentication. Do not send client_id in customer API requests. RouteIQ resolves the client from the API key.

$apiKey = "riq_test_YOUR_API_KEY"
$headers = @{ Authorization = "Bearer $apiKey" }

cURL example:

curl -H "Authorization: Bearer riq_test_YOUR_API_KEY" \
  https://gorouteiq.com/api/v1/me

Test vs live keys

Test keys

Use riq_test_... keys while validating payloads, response handling, and integration behavior. Test keys write to Test inventory, Test order history, Test routing runs, and Test report/export views.

Live keys

Use riq_live_... keys for production traffic after your workflow is ready. Live keys write to Live inventory, Live order history, Live routing runs, and Live report/export views.

Dashboard and Files page Data Mode follow this same split: Live shows live data only, Test shows test data only, and All includes both with an environment column in report exports.

Warehouse identifiers

In customer-facing API payloads, warehouse_id means the Warehouse ID configured on the Warehouses page. This is normally the customer’s own warehouse/location ID, such as 001, 002, 003, or any ID the customer entered during setup.

warehouse_id

The Warehouse ID customers send in inventory payloads and receive in routing responses.

warehouse_name

Readable warehouse name from the Warehouses page. Use it for display and reporting.

Inventory sync requires the Warehouse ID to exist and be enabled on the Warehouses page. Disabled warehouses are rejected until they are re-enabled.

API field contract

RouteIQ routing responses are designed around one execution rule: create downstream shipment or work records from shipments[].

Field Meaning Use this when...
warehouse_id The customer-facing Warehouse ID configured on the Warehouses page. Identifying the selected ship-from warehouse in customer systems.
warehouse_name Readable warehouse name from the Warehouses page. Showing decisions to users or reports.
preferred_warehouse The top-ranked warehouse based on routing control settings, proximity/transit, and available data. Reporting and explaining the ideal warehouse, including on NONE results.
selected_warehouse Convenience summary field populated only when exactly one warehouse was selected. Displaying single-warehouse decisions. For split routes this is null.
selected_warehouses[] Compact summary of all warehouses selected for the route. Displaying selected origins for full, partial, split, or partial-split decisions.
shipment_count Number of shipment records RouteIQ selected for the order. Quickly identifying single-shipment, split, partial, and no-route outcomes.
shipments[] Executable shipment instructions. Each item is one selected warehouse shipment. Primary integration field Creating downstream shipment/work records.
shipments[].selected_warehouse The warehouse selected for that shipment. Setting the ship-from warehouse for each downstream shipment.
shipments[].lines[] The SKU quantities to ship from that shipment’s selected warehouse. Passing pick/ship quantities to a WMS, OMS, ERP, or fulfillment workflow.
unfulfilled_lines[] Requested quantities RouteIQ could not allocate. Backorder, replenishment, exception, or customer-service workflows.
policy_outcome Policy result for the selected route: clear, warned, or blocked. Separating clean routes from routes allowed with warnings or blocked by rules.
policy_warning_count Number of warning codes returned. Filtering routes that need operator review.
policy_warning_codes[] Machine-readable warning codes returned when a rule is set to Warn. Building review queues or reporting on allowed-but-flagged decisions.
policy_blocked_code Machine-readable blocked policy code when a rule blocks a route. Classifying blocked route outcomes.
policy_messages[] Human-readable messages explaining policy warnings or blocks. Showing operators why RouteIQ allowed, warned, or blocked a route.
routing_quality Customer-facing quality label such as Optimal, Suboptimal, Split, or Unroutable. Reporting, dashboards, and customer-service summaries.
decision_driver The primary structured reason RouteIQ selected or could not select a route. Explaining exceptions, suboptimal routes, and unroutable orders.
explanation.item_control_applied true when one or more active Item Control rules affected the order. Auditing SKU-level routing controls that changed warehouse eligibility, split/partial behavior, or route availability.
explanation.item_control_skus[] SKUs on the order that matched active Item Control rules. Identifying which items caused a controlled routing decision.
explanation.item_control_rules[] Readable summaries of the Item Control rules that applied. Showing operators why a SKU was restricted, preferred, excluded, blocked, or flagged.
explanation.item_control_flags[] Machine-friendly flags such as warehouse_restricted, do_not_split, or do_not_partial. Building audit views or exception workflows around SKU-level controls.
unroutable_reason_code Stable machine-readable code for NONE results, such as invalid_destination_zip or no_inventory_available. Automating exception queues and customer-service workflows.
recommended_action Suggested next step, such as correcting a ZIP, adding inventory, or changing routing rules. Turning exceptions into clear follow-up work.
For fulfillment automation, use shipments[]. A full shipment has one shipment object. A split shipment has multiple shipment objects. A NONE result has shipment_count: 0 and an empty shipments[]. Use selected_warehouse and selected_warehouses[] for display/summary only.

Routing Profiles

Routing Profiles let you apply different routing rules for specific partners, channels, marketplaces, or customer groups without changing your default routing control settings.

To use a Routing Profile through the API, include the optional partner_id field on the order. RouteIQ compares that value to enabled Routing Profiles for the client.

Field Required Description
partner_id No Optional order-level identifier used to match an enabled Routing Profile. If omitted or unmatched, RouteIQ uses the client's default routing control settings.
{
  "external_order_id": "AMZ-1001",
  "destination_zip": "90210",
  "partner_id": "871",
  "lines": [
    {
      "sku": "SKU-123",
      "quantity": 2,
      "unit_value": 24.99
    }
  ]
}

New API integrations and CSV templates should use partner_id as the standard field name.

Item Control

Item Control rules are configured inside RouteIQ and apply by SKU during API and CSV routing. API callers do not send Item Control rules in the order payload. Instead, send normal order lines, and RouteIQ automatically applies any active rules for those SKUs.

Item Control can affect warehouse eligibility, warehouse ranking, split behavior, partial fulfillment behavior, max transit limits, external-fulfillment handling, and do-not-route/manual-review outcomes.

Rule behavior Routing effect
Restrict to selected warehouses Only the configured warehouses are eligible for that SKU. If fallback is blocked and those warehouses cannot fulfill, the order can return NONE.
Prefer selected warehouses Configured warehouses are ranked ahead of other eligible warehouses when they can satisfy the route.
Exclude selected warehouses Configured warehouses are skipped for that SKU.
Do not split SKU RouteIQ avoids splitting that SKU across warehouses.
Do not partial SKU RouteIQ avoids partially fulfilling that SKU.
Drop ship / vendor fulfilled RouteIQ marks the SKU as outside normal warehouse routing and can return an external-fulfillment or blocked decision.
Hold / manual review RouteIQ blocks warehouse routing for that SKU and returns an explanatory NONE decision.

When Item Control applies, API responses include Item Control details inside the order result explanation object. Report exports also expose Item Control audit fields in the Latest Order Routing Detail report.

"explanation": {
  "item_control_applied": true,
  "item_control_skus": ["21763"],
  "item_control_flags": ["warehouse_restricted", "do_not_split", "do_not_partial"],
  "item_control_notes": ["SKU must ship from Lansing"],
  "item_control_rules": [
    {
      "sku": "21763",
      "summary": "SKU 21763: Restrict to selected warehouses | restricted warehouses: Lansing MI; do not split SKU; do not partial SKU"
    }
  ]
}

Order request fields

These fields are accepted by POST /api/v1/orders/route and inside each object in POST /api/v1/orders/batch-route.

Field Required? Type Meaning
external_order_id Required if order_id is not sent String Customer-facing order ID. Preferred field name for integrations.
order_id Required if external_order_id is not sent String Alternate order ID field. RouteIQ accepts either external_order_id or order_id.
destination_zip Yes String Ship-to ZIP used for transit/proximity ranking. Invalid ZIPs return status: NONE with unroutable_reason_code: invalid_destination_zip.
lines Required if items is not sent Array Order lines to route. Preferred field name for integrations.
items Required if lines is not sent Array Alternate field name for order lines. RouteIQ accepts either lines or items.
lines[].sku Yes String SKU/item identifier to match against synced inventory.
lines[].quantity Yes Integer Units requested. Must be at least 1.
lines[].unit_value No Number Per-unit value used for shipment value, line value, and minimum split/partial value rules when enabled.
is_vip No Boolean When true, this order routes ahead of non-VIP orders during Priority Allocation. Use JSON true or false.
priority_level No Integer Priority rank used during Priority Allocation. Lower numbers route first. RouteIQ does not normalize the scale; it simply sorts ascending.
order_created_at No ISO timestamp/string Used as an age tie-breaker during Priority Allocation. Older timestamps route first when VIP and priority are tied or blank.
carrier No String Optional carrier value for shipping context, reporting, and future carrier-specific routing rules.
ship_method No String Optional ship method/service value for shipping context, reporting, and future service-specific routing rules.
raw_order_data No Object Optional source-system metadata stored for traceability. RouteIQ does not require this for routing.

Inventory request fields

These fields are accepted by POST /api/v1/inventory. Inventory is synced by SKU and warehouse.

Field Required? Type Meaning
source_name No String Name of the system or process that sent the inventory sync, such as wms hourly sync.
inventory Yes Array Inventory rows to upsert. API requests accept up to 10,000 rows per request. Plan-level inventory upload limits also apply.
inventory[].sku Yes String SKU/item identifier used for routing.
inventory[].warehouse_id Required String Preferred warehouse identifier. This is the Warehouse ID configured on the Warehouses page.
inventory[].external_warehouse_id No String Backward-compatible alias for warehouse_id.
inventory[].quantity_available Required if available_qty is not sent Integer Available quantity for that SKU at that warehouse. Send 0 to mark a known SKU/location out of stock.
inventory[].available_qty Required if quantity_available is not sent Integer Alternate available quantity field.
inventory[].unit_value No Number Optional SKU value. Used when order lines do not provide unit_value and value-based rules need a value.
inventory[].sku_description No String Optional product description for display, troubleshooting, and reporting.
Each SKU can appear once per warehouse in a single inventory sync request. Missing rows are not deleted. To mark a SKU/location out of stock, send the row with quantity 0. A successful inventory sync releases active RouteIQ reservations for that client because the new snapshot becomes the current inventory source of truth.

Priority Allocation

Priority Allocation determines which queued orders get first access to scarce inventory inside the current routing run. It is separate from Use Inventory Availability.

When Use Inventory Availability is enabled, RouteIQ checks available inventory and persists routed allocations as reservations. When Priority Allocation is also enabled, RouteIQ sorts the current run before allocating inventory:

  1. VIP first: is_vip=true orders route before non-VIP orders.
  2. Priority level next: orders with priority_level route before blank priority levels. Among populated values, lower numbers route first. Example: 1 before 2, and 2 before 10.
  3. Oldest order next: order_created_at is used as the next tie-breaker. Older orders route first.
  4. Stable final tie-breaker: RouteIQ uses request/database order to keep results deterministic when all other priority fields are tied.
Priority Allocation only applies to orders included in the current routing run. If orders are sent one at a time, RouteIQ cannot prioritize against future VIP or high-priority orders it has not received yet. For v1, send orders together when you want RouteIQ to allocate scarce inventory across a priority queue.

Example

{
  "orders": [
    {
      "external_order_id": "STANDARD-1001",
      "destination_zip": "08825",
      "is_vip": false,
      "priority_level": 2,
      "order_created_at": "2026-05-21T10:00:00Z",
      "lines": [{ "sku": "SKU-A", "quantity": 5 }]
    },
    {
      "external_order_id": "VIP-1002",
      "destination_zip": "08825",
      "is_vip": true,
      "priority_level": 10,
      "order_created_at": "2026-05-21T10:05:00Z",
      "lines": [{ "sku": "SKU-A", "quantity": 5 }]
    }
  ]
}

In this example, the VIP order routes first even though its numeric priority_level is higher. VIP status is evaluated before numeric priority.

If Priority Allocation is disabled, RouteIQ still reserves inventory when Use Inventory Availability is enabled, but it follows the upload/API request order instead of sorting by is_vip, priority_level, and order_created_at. If those optional fields are missing while Priority Allocation is enabled, RouteIQ falls back to stable request/database order.

Response field reference

RouteIQ responses provide a decision summary plus executable shipment instructions. Integrations should create downstream shipment/work records from shipments[].

Order result fields

Field Meaning Use this when...
order_idThe order ID RouteIQ routed.Matching the response to the source order.
routing_decision_idRouteIQ decision ID.Support, troubleshooting, or linking to saved decision history.
statusFulfillment result: FULL, SPLIT, PARTIAL, PARTIAL_SPLIT, or NONE.Classifying the outcome.
routing_qualityCustomer-facing quality label such as Optimal, Suboptimal, Split, or Unroutable.Reporting and customer-service summaries.
reasonShort customer-facing reason for the result.Showing a concise outcome reason.
profile.appliedtrue when an enabled Routing Profile matched the order; otherwise false.Knowing whether default settings or a profile override controlled the route.
profile.nameName of the applied Routing Profile, or Default when no profile matched.Displaying or reporting which routing rule set was used.
profile.partner_idThe matched Routing Profile partner ID, or null when no profile matched.Auditing partner/channel-specific routing behavior.
policy_outcomePolicy result: clear, warned, or blocked.Knowing whether a route was clean, allowed with warnings, or blocked by settings.
policy_warning_countNumber of warning codes returned.Filtering routes that need operator review.
policy_warning_codes[]Machine-readable warning codes such as split_shipment_warned or max_transit_days_warned.Automating exception queues and analytics.
policy_blocked_codeMachine-readable blocked policy code when a rule prevents a route.Classifying blocked route outcomes.
policy_messages[]Human-readable policy warning/block explanations.Showing why RouteIQ allowed, warned, or blocked a route.
preferred_warehouseTop-ranked warehouse based on routing control settings, proximity/transit, and available data.Explaining the ideal warehouse. This may appear even when status is NONE.
selected_warehouseSelected warehouse summary when exactly one warehouse was selected; otherwise null.Displaying single-warehouse decisions.
selected_warehouses[]All warehouses selected for the route.Displaying the selected origins for full, split, partial, and partial-split results.
shipment_countNumber of shipment objects selected for the order.Knowing how many downstream shipment/work records to create.
shipments[]Executable shipment instructions. Each object is one selected warehouse shipment.Primary integration field Creating fulfillment work.
shipments[].selected_warehouse.warehouse_idSelected ship-from Warehouse ID for that shipment.Mapping the shipment back to the customer’s WMS, OMS, ERP, or fulfillment system.
shipments[].lines[].skuSKU selected for that shipment.Creating shipment lines.
shipments[].lines[].ship_qtyQuantity to ship from that shipment’s selected warehouse.Creating shipment lines.
unfulfilled_lines[]Requested quantities RouteIQ could not allocate.Backorder, replenishment, or exception workflows.
unroutable_reason_codeStable code for NONE results.Automating exception handling.
unroutable_categoryHigh-level issue type, such as inventory, rules, or invalid order data.Grouping exceptions.
unroutable_reasonHuman-readable explanation for why no shippable route was selected.Showing operators what needs attention.
recommended_actionSuggested next step for an unroutable order.Turning exceptions into work queues.
explanation.selected_pathRoute path selected by the engine.Auditing whether the result was full, split, partial, or none.
explanation.ranked_warehouses[]Warehouses in ranked consideration order with rank, warehouse_id, and warehouse_name.Showing proximity/ranking context.
explanation.decision_driverStructured primary driver for the decision or exception.Explaining the main reason for a decision.

Routing run response wrapper fields

Field Meaning
routing_run_idShared run ID for the routing request. Single-order routing returns one result under this run; batch routing returns many.
client_run_numberClient-facing run number when available.
client_idRouteIQ client ID resolved from the API key.
statusRouting run processing status.
orders_consideredNumber of orders RouteIQ attempted to route.
orders_routedNumber of order results returned.
full_count, split_count, partial_count, partial_split_count, none_countSummary counts by fulfillment result/status.
results[]One order result object per routed order. For /orders/route, this array contains exactly one result.

Policy behavior: Allow, Warn, Block

RouteIQ routing control settings can allow a route, allow it with a warning, or block it. The customer API exposes that result through the policy_* fields on each order response.

Mode API behavior Typical response
Allow RouteIQ may select the route without creating a policy warning. policy_outcome: "clear"
Warn RouteIQ may select the route, but flags it for review. policy_outcome: "warned", warning codes, and policy messages.
Block RouteIQ avoids the blocked route. If no compliant route is available, the result may be NONE. policy_outcome: "blocked" or a fallback route with clear/warned policy fields.

Common policy codes

  • split_shipment_warned / split_shipment_blocked
  • partial_shipment_warned / partial_shipment_blocked
  • max_transit_days_warned / max_transit_days_blocked
  • minimum_shipment_value_warned / minimum_shipment_value_blocked
A warning means RouteIQ intentionally returned a usable route and flagged it. A block means RouteIQ tried to avoid the blocked route; if no allowed fallback exists, the order can return status: NONE with policy and unroutable details.

Validate an API key

GET/api/v1/me

Use this endpoint to confirm that an API key is active and scoped to the expected client.

Invoke-RestMethod `
  -Uri "https://gorouteiq.com/api/v1/me" `
  -Method GET `
  -Headers $headers | ConvertTo-Json -Depth 5
{
  "status": "ok",
  "api_key_id": 5,
  "client_id": 9,
  "environment": "test",
  "key_prefix": "riq_test_bda75e17e",
  "name": "Integration test key",
  "subscription_status": "trialing",
  "subscription_tier": "starter"
}

Sync inventory

POST/api/v1/inventory

Upserts current available inventory by SKU and warehouse. This endpoint feeds the same inventory snapshot RouteIQ uses for API and CSV routing. It updates inventory only; it does not count against routed-order usage.

RouteIQ is not your WMS, ERP, or inventory system of record. Inventory synced to RouteIQ is treated as the client’s latest routing snapshot. When Use Inventory Availability is enabled, RouteIQ uses that snapshot to determine what can still be allocated to new orders.

Recommended integration pattern: sync inventory on the customer’s preferred schedule, then route orders. Between inventory syncs, RouteIQ protects against double-promising the same units by reducing available inventory as orders are routed.

Sync lifecycle: a successful inventory sync refreshes the source inventory snapshot. Missing rows are preserved; send quantity 0 to mark a SKU/warehouse out of stock.
Why keep syncing: RouteIQ reduces available inventory as orders are routed, but your WMS, ERP, or commerce platform remains the source of truth for receipts, cancellations, adjustments, and shipments outside RouteIQ. Sync inventory on a cadence that matches how quickly stock changes in your operation.
warehouse_id means the Warehouse ID configured on the Warehouses page. Each warehouse in the payload must already exist and be enabled for that client.
{
  "source_name": "nightly inventory sync",
  "inventory": [
    {
      "sku": "SKU-A",
      "warehouse_id": "001",
      "quantity_available": 50,
      "unit_value": 12.50,
      "sku_description": "Sample item"
    },
    {
      "sku": "SKU-A",
      "warehouse_id": "002",
      "quantity_available": 10
    }
  ]
}

PowerShell example:

$body = @{
  source_name = "nightly inventory sync"
  inventory = @(
    @{ sku = "SKU-A"; warehouse_id = "001"; quantity_available = 50; unit_value = 12.50 },
    @{ sku = "SKU-A"; warehouse_id = "002"; quantity_available = 10 }
  )
} | ConvertTo-Json -Depth 8

Invoke-RestMethod `
  -Uri "https://gorouteiq.com/api/v1/inventory" `
  -Method POST `
  -Headers $headers `
  -ContentType "application/json" `
  -Body $body

Also accepted:

  • available_qty instead of quantity_available
  • external_warehouse_id instead of warehouse_id, for older integrations

Rules and limits:

  • Maximum inventory API request body: up to 10,000 inventory rows per request.
  • Plan-level inventory upload limits are also enforced: Trial 50,000 rows/upload, Starter 150,000 rows/upload, Pro 500,000 rows/upload, and Enterprise custom.
  • Each SKU can appear once per warehouse in a single inventory sync request.
  • Missing rows are not deleted. To mark a SKU/location out of stock, send quantity_available: 0.
{
  "client_id": 9,
  "ingest_run_id": 123,
  "rows_received": 2,
  "rows_upserted": 2,
  "rows_inserted": 1,
  "rows_updated": 1,
  "rows_unchanged": 0,
  "rows_deleted": 0
}

Route one order

POST/api/v1/orders/route

Routes one customer order. The order may contain one line or many lines. A successful request creates a one-order routing run, writes the API order into canonical order history, returns the standard routing-run response shape, and increments routed-order usage by 1.

{
  "external_order_id": "API-1001",
  "destination_zip": "08825",
  "lines": [
    { "sku": "SKU-A", "quantity": 1, "unit_value": 12.50 }
  ]
}

Also accepted: order_id instead of external_order_id, and items instead of lines.

RouteIQ ranks enabled warehouses using customer routing control settings and available transit data. The response uses the same wrapper as /orders/batch-route; read the single decision from results[0]. The routing run and order decision appear in Dashboard history, Files page routing runs, run-level exports, and report exports for the API key environment.

Route a batch of orders

POST/api/v1/orders/batch-route

Routes a synchronous batch of up to 5,000 orders and returns the standard routing-run response shape with one shared routing_run_id. A successful request writes the API orders into canonical order history and increments routed-order usage by the number of orders processed, including orders that return NONE.

Batch routing is synchronous. First-time origin/destination transit lanes may take longer while RouteIQ resolves and caches transit data. Repeated lanes are typically faster. Async or managed batch processing is available upon request for larger scheduled bulk files.
{
  "orders": [
    {
      "external_order_id": "API-BATCH-1001",
      "destination_zip": "08825",
      "lines": [
        { "sku": "SKU-A", "quantity": 1, "unit_value": 12.50 }
      ]
    },
    {
      "external_order_id": "API-BATCH-1002",
      "destination_zip": "48837",
      "lines": [
        { "sku": "SKU-B", "quantity": 1, "unit_value": 12.50 }
      ]
    }
  ]
}

Each external_order_id/order_id must be unique within a batch request.

Priority Allocation controls how RouteIQ orders queued work before inventory is allocated. When Use Inventory Availability is enabled, RouteIQ reduces available inventory as orders are routed so the same units are not promised to multiple orders between inventory syncs. If Priority Allocation is disabled, RouteIQ still protects available inventory but follows upload/API order instead of VIP, priority level, and order timestamp fields.

When inventory is enabled, RouteIQ routes visible queued orders in this priority order:

  • is_vip=true orders route first.
  • priority_level routes next. Lower numbers route first, so priority 1 routes before 2, and 2 routes before 10.
  • order_created_at routes next. Older timestamps route first when VIP and priority are tied or blank.
  • Request/database order is used as a deterministic final tie-breaker.
Priority Allocation only applies to orders included in the current routing run. If orders are sent one at a time, RouteIQ cannot prioritize against future VIP or high-priority orders it has not received yet. For v1, send orders together when you want RouteIQ to allocate scarce inventory across a priority queue.

Inventory sync behavior: client_inventory remains the latest inventory snapshot from the client. RouteIQ uses effective availability while routing, meaning the synced snapshot is reduced by inventory already allocated to prior routed orders. A successful new inventory sync refreshes the source snapshot.

Batch API runs appear in the same Dashboard, Files page routing history, run-level CSV exports, and report exports as CSV-routed runs. Test and Live visibility follows the API key environment. For report endpoint details and CSV field definitions, see the Report Export API.

Response fields

/api/v1/orders/route and /api/v1/orders/batch-route both return a routing-run wrapper. For single-order routing, results[] contains exactly one order result. For fulfillment automation, use shipments[] inside each result. Each item in shipments[] is one selected warehouse shipment.

{
  "routing_run_id": 205,
  "client_run_number": 40,
  "client_id": 21,
  "status": "completed",
  "orders_considered": 1,
  "orders_routed": 1,
  "full_count": 1,
  "split_count": 0,
  "partial_count": 0,
  "partial_split_count": 0,
  "none_count": 0,
  "results": [
    {
      "order_id": "API-1001",
      "routing_decision_id": 3519,
      "status": "FULL",
      "routing_quality": "Optimal",
      "reason": "Full shipment allowed",
      "policy_outcome": "clear",
      "policy_warning_count": 0,
      "policy_warning_codes": [],
      "policy_blocked_code": null,
      "policy_messages": [],
      "unroutable_reason_code": null,
      "unroutable_category": null,
      "unroutable_reason": null,
      "recommended_action": null,
      "total_shipment_value": 12.5,
      "preferred_warehouse": {
        "warehouse_id": "001",
        "warehouse_name": "NYC"
      },
      "selected_warehouse": {
        "warehouse_id": "001",
        "warehouse_name": "NYC"
      },
      "selected_warehouses": [
        {
          "warehouse_id": "001",
          "warehouse_name": "NYC"
        }
      ],
      "shipment_count": 1,
      "shipments": [
        {
          "selected_warehouse": {
            "warehouse_id": "001",
            "warehouse_name": "NYC"
          },
          "lines": [
            {
              "sku": "SKU-A",
              "ship_qty": 1
            }
          ]
        }
      ],
      "unfulfilled_lines": [],
      "explanation": {
        "selected_path": "FULL",
        "ranked_warehouses": [
          { "rank": 1, "warehouse_id": "001", "warehouse_name": "NYC" },
          { "rank": 2, "warehouse_id": "002", "warehouse_name": "Austin" },
          { "rank": 3, "warehouse_id": "003", "warehouse_name": "Los Angeles" }
        ],
        "decision_driver": {
          "code": "optimal_preferred_full",
          "message": "All items were available in the preferred warehouse NYC.",
          "sku": null,
          "required_qty": null,
          "available_qty": null,
          "short_qty": null,
          "warehouse": {
            "warehouse_id": "001",
            "warehouse_name": "NYC"
          }
        }
      }
    }
  ]
}
  • shipments[]: primary execution field. Create one downstream shipment/work record per object.
  • shipments[].selected_warehouse.warehouse_id: ship-from Warehouse ID.
  • shipments[].lines[].ship_qty: quantity to ship from that warehouse.
  • shipment_count: number of shipment objects returned.
  • preferred_warehouse: top-ranked warehouse for reporting and diagnostics. It is not necessarily the ship-from warehouse.
  • selected_warehouse: populated only when exactly one warehouse was selected; null for split decisions.
  • selected_warehouses[]: compact summary of all warehouses selected for the order.
  • policy_outcome and related policy_* fields: whether the route was clear, warned, or blocked by routing control settings.
  • unfulfilled_lines[]: quantities that could not be allocated.

Split route with policy warnings

When a route uses multiple warehouses, selected_warehouse is null, selected_warehouses[] lists every selected origin, and shipments[] remains the execution payload.

{
  "order_id": "API-SPLIT-1001",
  "status": "SPLIT",
  "routing_quality": "Split",
  "reason": "Split shipment allowed",
  "policy_outcome": "warned",
  "policy_warning_count": 2,
  "policy_warning_codes": [
    "max_transit_days_warned",
    "split_shipment_warned"
  ],
  "policy_blocked_code": null,
  "policy_messages": [
    "Maximum transit days is set to Warn, so RouteIQ allowed this split shipment and flagged it for review.",
    "Split shipments are set to Warn, so RouteIQ allowed this split route and flagged it for review."
  ],
  "preferred_warehouse": {
    "warehouse_id": "001",
    "warehouse_name": "NYC"
  },
  "selected_warehouse": null,
  "selected_warehouses": [
    { "warehouse_id": "001", "warehouse_name": "NYC" },
    { "warehouse_id": "002", "warehouse_name": "Austin" }
  ],
  "shipment_count": 2,
  "shipments": [
    {
      "selected_warehouse": { "warehouse_id": "001", "warehouse_name": "NYC" },
      "lines": [{ "sku": "API-SPLIT-NYC", "ship_qty": 2 }]
    },
    {
      "selected_warehouse": { "warehouse_id": "002", "warehouse_name": "Austin" },
      "lines": [{ "sku": "API-SPLIT-AUSTIN", "ship_qty": 2 }]
    }
  ],
  "unfulfilled_lines": []
}
Integration rule: use selected_warehouse/selected_warehouses[] for display and summary, but use shipments[] to create fulfillment work.

Status values

status describes the fulfillment result. routing_quality describes whether the selected route was ideal, suboptimal, split, or unroutable under the current settings.

  • FULL: all requested units can ship from one warehouse. shipments[] has one object.
  • SPLIT: all requested units can ship, but more than one warehouse is required. shipments[] has multiple objects.
  • PARTIAL: some units can ship from one warehouse, but not all requested units. unfulfilled_lines[] identifies the shortage.
  • PARTIAL_SPLIT: some units can ship across multiple warehouses, but not all requested units. shipments[] and unfulfilled_lines[] are both populated.
  • NONE: no route is available. shipment_count is 0, shipments[] is empty, and unfulfilled_lines[] identifies the affected SKU quantities.

Routing quality values

  • Optimal: RouteIQ selected the best available route under the active routing control settings.
  • Suboptimal: RouteIQ found a shippable route, but had to fall back from the top preferred or ideal route because of inventory, rules, or another constraint.
  • Split: RouteIQ used more than one warehouse or a split/partial-split path.
  • Unroutable: RouteIQ could not create a shippable allocation.

Demo and regression CSVs

RouteIQ includes demo CSVs that can be used to validate routing behavior in a safe test client.

  • data/demo/routeiq_demo_inventory.csv: inventory snapshot designed to show full, split, no-stock, and preference-control behavior.
  • data/demo/routeiq_demo_orders.csv: primary demo order set for settings walkthroughs.
  • data/demo/routeiq_demo_orders_test2.csv: same demo orders with different order IDs. Use this after the primary order file to regression-test inventory protection across separate routing runs.
The -2 file is mainly a regression tool. The sales demo can usually use one inventory file and one primary orders file, while explaining RouteIQ's behind-the-scenes protection against double-promising inventory between syncs.

Limits and usage

RouteIQ enforces customer plan limits before routing work begins.

  • POST /api/v1/orders/route counts as 1 routed order after a successful decision is saved and written to routing history.
  • POST /api/v1/orders/batch-route counts each order in the batch after successful decisions are saved and written to routing history.
  • POST /api/v1/inventory does not count as routed-order usage, but inventory row limits still apply.
  • Inventory is snapshot-based when Use Inventory Availability is enabled. RouteIQ reduces effective availability as orders are routed so the same units are not promised twice between inventory syncs.
  • Batch route requests are limited to 5,000 orders per synchronous request for platform reliability. Async or managed batch processing is available upon request for larger scheduled bulk files.
  • Required order fields: order_id or external_order_id, destination_zip, sku, and quantity. Recommended optional fields: unit_value, is_vip, priority_level, and order_created_at.
  • When Priority Allocation is enabled, RouteIQ routes is_vip=true orders first, then orders with a priority_level value before blank priority levels. Among populated priority levels, lower numbers route first. RouteIQ then uses older order_created_at timestamps, then stable request/database order.
  • is_vip is a boolean. Send true or false in API JSON. priority_level is an integer where lower numbers route first. RouteIQ does not normalize the scale; it simply sorts ascending.
  • Priority Allocation only applies to orders in the current routing run. If orders are sent individually, RouteIQ cannot hold inventory for future priority orders it has not received.
  • destination_zip must be a valid 5-digit ZIP. Invalid ZIPs return status: NONE with unroutable_reason_code: invalid_destination_zip.
  • Inventory sync requests allow up to 10,000 rows per API request. Plan-level inventory upload limits are Trial 50,000 rows/upload, Starter 150,000 rows/upload, Pro 500,000 rows/upload, and Enterprise custom.
  • Required inventory fields: warehouse_id, sku, and an available quantity field such as quantity_available. Optional: unit_value.
  • When a routing request exceeds the client’s plan usage, RouteIQ returns 402 and does not increment usage.

Errors

  • 401: missing, invalid, or revoked API key.
  • 402: account/subscription is not active, a trial/plan routed-order limit was reached, or an upload exceeds a plan limit.
  • 413: synchronous order batch exceeds the 5,000-order platform safety cap.
  • 400: invalid payload, missing order ID, missing lines, unknown Warehouse ID, disabled Warehouse ID, duplicate inventory rows, or duplicate order IDs in a batch.
  • 422: request body fails validation.
  • 500: unexpected server error.

Example invalid key response:

{
  "detail": "Invalid or revoked API key"
}

Example usage-limit response:

{
  "detail": "Your free trial includes up to 15 routed orders total. You have 0 remaining, and this run contains 1. Choose a plan on the Billing page or contact RouteIQ for a larger test."
}

Example Warehouse ID response:

{
  "detail": "Unknown Warehouse ID: Warehouse ID must be setup and enabled in the Warehouses page. Your enabled Warehouse ID's are: 001, 002, 003"
}

Inventory-aware vs routing-only mode

Use Inventory Availability is controlled in Routing Control.

  • Enabled: RouteIQ checks SKU inventory, subtracts active RouteIQ reservations, and only selects warehouses with effective available quantity. Routed allocations are saved as active reservations until the next inventory sync or same-order reroute releases them.
  • Inventory timing: Inventory availability is based on the latest inventory snapshot synced to RouteIQ minus active reservations created by prior routing decisions.
  • Disabled: RouteIQ ignores SKU inventory and does not apply or create inventory reservations. RouteIQ recommends the best enabled warehouse using transit and configured warehouse rules. Transit ranking considers all enabled warehouses.
  • When disabled, route responses are routing recommendations, not inventory‑confirmed fulfillment decisions.

Security notes

  • Store API keys only in server‑side systems or secure integration tools.
  • Do not place API keys in public repos, browser JavaScript, or shared spreadsheets.
  • RouteIQ stores only hashed API keys and shows the secret only once at creation.
  • Revoke unused keys from Account → API Access.