Appearance
Fan-out Dispatches
The fan-out API is the generic multi-store write framework. It follows a three-step lifecycle: preview (validate the payload against each target store), commit (dispatch to all valid targets), and poll (track per-store apply progress).
Async operations are documented in Async and Polling. For staging the hostcom file that the hostcom_batch operation consumes, see Hostcom Files.
Permission Model
Every fan-out call requires two permissions:
rorcex:fanout.execute— required on all preview, commit, and get endpoints- The operation-specific permission listed on each endpoint below
Preview Dispatch
Validate a payload against each target store before committing. RORCex checks that each store's lane is reachable and that the payload is accepted — no writes occur at this stage.
POST /v1/fanout/{operation_type}/previewAuthentication: OAuth Token (service_account or user)
Permission: rorcex:fanout.execute + operation-specific (see below)
Path Parameters
| Parameter | Type | Description |
|---|---|---|
operation_type | string | One of hostcom_batch or inventory_adjustment |
Request Body
json
{
"store_org_ids": ["org_00000k1L2m3N4o5", "org_00000a1B2c3D4e5"],
"payload": {}
}| Field | Type | Required | Description |
|---|---|---|---|
store_org_ids | array | Yes | Organization hashkeys for the target stores |
payload | object | Yes | Operation-specific payload (see below) |
hostcom_batch payload
Operation permission: rorcex:hostcom-batches.dispatch
json
{
"store_org_ids": ["org_00000k1L2m3N4o5"],
"payload": {
"file_id": "hkx_00000k1L2m3N4o5",
"note": "Weekly price change"
}
}| Field | Type | Required | Description |
|---|---|---|---|
file_id | string | Yes | A staged hostcom file — obtain from POST /v1/hostcom/files or POST /v1/hostcom/files/author |
note | string | No | Free-text annotation attached to the dispatch |
inventory_adjustment payload
Operation permission: rorcex:inventory-adjustments.create
json
{
"store_org_ids": ["org_00000k1L2m3N4o5"],
"payload": {
"product_code": "001234567890",
"reason_code": "SHRINK",
"quantity": -3
}
}| Field | Type | Required | Description |
|---|---|---|---|
product_code | string | Yes | UPC or internal item code |
reason_code | string | Yes | Reason for the adjustment (e.g., SHRINK, RECEIVE, WASTE) |
quantity | integer | Yes | Signed adjustment quantity (negative to reduce, positive to increase) |
Response
json
{
"dispatch_id": "01J9XR4K7P8VN2YQ6ZB3TGD0WC",
"operation_type": "hostcom_batch",
"status": "previewed",
"can_commit": true,
"targets": [
{
"store_org_id": "org_00000k1L2m3N4o5",
"validation_status": "valid",
"validation_message": null
},
{
"store_org_id": "org_00000a1B2c3D4e5",
"validation_status": "invalid",
"validation_message": "Lane is offline"
}
]
}Status: 200 OK
| Field | Type | Description |
|---|---|---|
dispatch_id | string | Unique identifier — use in commit and poll requests |
operation_type | string | Echo of the requested operation type |
status | string | previewed if all targets validated; preview_failed if one or more targets were invalid |
can_commit | boolean | true when at least one target is valid and the dispatch can be committed |
targets | array | Per-store validation results |
targets[].store_org_id | string | Target store organization hashkey |
targets[].validation_status | string | valid or invalid |
targets[].validation_message | string|null | Human-readable explanation when invalid |
Errors
See Errors for shared error envelope format.
Commit Dispatch
Dispatch a previewed payload to all valid target stores. The commit is asynchronous — poll GET /v1/fanout/{dispatch_id} to track per-store apply progress.
POST /v1/fanout/{dispatch_id}/commitAuthentication: OAuth Token (service_account or user)
Permission: rorcex:fanout.execute + operation-specific (same as preview)
Path Parameters
| Parameter | Type | Description |
|---|---|---|
dispatch_id | string | The dispatch_id returned from the preview step |
Request Body
Empty body.
Response
json
{
"dispatch_id": "01J9XR4K7P8VN2YQ6ZB3TGD0WC",
"status": "committing",
"poll_url": "/api/v1/fanout/01J9XR4K7P8VN2YQ6ZB3TGD0WC"
}Status: 202 Accepted
| Field | Type | Description |
|---|---|---|
dispatch_id | string | Echo of the committed dispatch identifier |
status | string | Always committing immediately after commit |
poll_url | string | Relative URL to poll for status updates |
Errors
See Errors for shared error envelope format.
Get Dispatch
Poll the status of a fan-out dispatch, including per-store apply progress.
GET /v1/fanout/{dispatch_id}Authentication: OAuth Token (service_account or user)
Permission: rorcex:fanout.execute + operation-specific (same as preview)
Path Parameters
| Parameter | Type | Description |
|---|---|---|
dispatch_id | string | The dispatch_id to retrieve |
Response
json
{
"dispatch_id": "01J9XR4K7P8VN2YQ6ZB3TGD0WC",
"operation_type": "hostcom_batch",
"status": "completed",
"committed_at": "2026-06-11T14:35:00Z",
"completed_at": "2026-06-11T14:37:42Z",
"targets": [
{
"store_org_id": "org_00000k1L2m3N4o5",
"validation_status": "valid",
"apply_status": "applied",
"apply_message": null,
"rorc_reference": "OP-00042"
},
{
"store_org_id": "org_00000a1B2c3D4e5",
"validation_status": "invalid",
"apply_status": "skipped",
"apply_message": "Skipped: failed validation during preview",
"rorc_reference": null
}
]
}Status: 200 OK
| Field | Type | Description |
|---|---|---|
dispatch_id | string | Dispatch identifier |
operation_type | string | hostcom_batch or inventory_adjustment |
status | string | Aggregate dispatch status (see table below) |
committed_at | string|null | ISO 8601 timestamp when the commit was accepted |
completed_at | string|null | ISO 8601 timestamp when all targets reached a terminal state |
targets | array | Per-store apply results |
targets[].store_org_id | string | Target store organization hashkey |
targets[].validation_status | string | valid or invalid (set during preview) |
targets[].apply_status | string | Per-store apply status (see table below) |
targets[].apply_message | string|null | Human-readable detail when errored or skipped |
targets[].rorc_reference | string|null | RORC operation reference ID, populated once the lane acknowledges the dispatch |
Dispatch Status Values
| Status | Description |
|---|---|
previewing | Preview is in progress |
preview_failed | All targets failed validation — cannot commit |
previewed | Preview complete — ready to commit |
committing | Commit accepted, applying to stores |
completed | All valid targets applied successfully |
partially_failed | Some targets applied; others errored |
errored | All targets errored during apply |
Per-Store Apply Status Values
| Status | Description |
|---|---|
pending | Queued, not yet sent to the lane |
applying | Sent to the lane, awaiting acknowledgement |
applied | Lane confirmed successful application |
skipped | Not attempted (e.g., failed preview validation) |
errored | Lane rejected or did not acknowledge within timeout |
Errors
See Errors for shared error envelope format.
List Dispatches
List fan-out dispatches with optional filtering.
GET /v1/fanoutAuthentication: OAuth Token (service_account or user)
Permission: rorcex:reports.view
Request Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
status | string | No | Filter by dispatch status (see status values above) |
operation_type | string | No | Filter by operation type: inventory_adjustment or hostcom_batch |
page | integer | No | Page number (default: 1) |
per_page | integer | No | Results per page, 1–100 (default: 50) |
Response
json
{
"data": [
{
"dispatch_id": "01J9XR4K7P8VN2YQ6ZB3TGD0WC",
"operation_type": "hostcom_batch",
"status": "completed",
"target_rollup": {
"pending": 0,
"applying": 0,
"applied": 12,
"skipped": 1,
"errored": 0
},
"requested_by_org_id": "org_00000z9Y8x7W6v5",
"requested_by_user_id": "usr_00000p4Q3r2S1t0",
"created_at": "2026-06-11T14:30:00Z",
"committed_at": "2026-06-11T14:35:00Z",
"completed_at": "2026-06-11T14:37:42Z",
"payload_preview": {
"file_id": "hkx_00000k1L2m3N4o5",
"note": "Weekly price change"
}
}
],
"meta": {
"current_page": 1,
"per_page": 50,
"total": 143,
"last_page": 3
}
}Status: 200 OK
| Field | Type | Description |
|---|---|---|
data | array | List of dispatch summaries |
data[].dispatch_id | string | Dispatch identifier |
data[].operation_type | string | hostcom_batch or inventory_adjustment |
data[].status | string | Aggregate dispatch status |
data[].target_rollup | object | Counts of targets in each apply status |
data[].requested_by_org_id | string | Organization hashkey of the requesting org |
data[].requested_by_user_id | string | User hashkey of the requestor |
data[].created_at | string | ISO 8601 creation timestamp |
data[].committed_at | string|null | ISO 8601 commit timestamp |
data[].completed_at | string|null | ISO 8601 completion timestamp |
data[].payload_preview | object | Abridged payload for display — does not include row data |
meta.current_page | integer | Current page number |
meta.per_page | integer | Results per page |
meta.total | integer | Total matching dispatches |
meta.last_page | integer | Last available page |
Errors
See Errors for shared error envelope format.
Changelog
| Date | Change |
|---|---|
| 2026-06-11 | Initial publication. |