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 enabledIf Use Inventory Availability is enabled, send current available quantity with POST /api/v1/inventory.
2Route each orderCall 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 decisionCreate 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 ordersSend 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 batchCall 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 resultsLoop 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:
- VIP first:
is_vip=true orders route before non-VIP orders.
- 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.
- Oldest order next:
order_created_at is used as the next tie-breaker. Older orders route first.
- 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_id | The order ID RouteIQ routed. | Matching the response to the source order. |
routing_decision_id | RouteIQ decision ID. | Support, troubleshooting, or linking to saved decision history. |
status | Fulfillment result: FULL, SPLIT, PARTIAL, PARTIAL_SPLIT, or NONE. | Classifying the outcome. |
routing_quality | Customer-facing quality label such as Optimal, Suboptimal, Split, or Unroutable. | Reporting and customer-service summaries. |
reason | Short customer-facing reason for the result. | Showing a concise outcome reason. |
profile.applied | true when an enabled Routing Profile matched the order; otherwise false. | Knowing whether default settings or a profile override controlled the route. |
profile.name | Name of the applied Routing Profile, or Default when no profile matched. | Displaying or reporting which routing rule set was used. |
profile.partner_id | The matched Routing Profile partner ID, or null when no profile matched. | Auditing partner/channel-specific routing behavior. |
policy_outcome | Policy result: clear, warned, or blocked. | Knowing whether a route was clean, allowed with warnings, or blocked by settings. |
policy_warning_count | Number 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_code | Machine-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_warehouse | Top-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_warehouse | Selected 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_count | Number 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_id | Selected ship-from Warehouse ID for that shipment. | Mapping the shipment back to the customer’s WMS, OMS, ERP, or fulfillment system. |
shipments[].lines[].sku | SKU selected for that shipment. | Creating shipment lines. |
shipments[].lines[].ship_qty | Quantity 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_code | Stable code for NONE results. | Automating exception handling. |
unroutable_category | High-level issue type, such as inventory, rules, or invalid order data. | Grouping exceptions. |
unroutable_reason | Human-readable explanation for why no shippable route was selected. | Showing operators what needs attention. |
recommended_action | Suggested next step for an unroutable order. | Turning exceptions into work queues. |
explanation.selected_path | Route 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_driver | Structured primary driver for the decision or exception. | Explaining the main reason for a decision. |
Routing run response wrapper fields
| Field |
Meaning |
routing_run_id | Shared run ID for the routing request. Single-order routing returns one result under this run; batch routing returns many. |
client_run_number | Client-facing run number when available. |
client_id | RouteIQ client ID resolved from the API key. |
status | Routing run processing status. |
orders_considered | Number of orders RouteIQ attempted to route. |
orders_routed | Number of order results returned. |
full_count, split_count, partial_count, partial_split_count, none_count | Summary 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.