List warehouse tasks
listWmsTasks · WMS · task:read
TaskPage · schema
cURL
Copy
curl --request GET \
"https://factoryflow-api.example.invalid/wms/v1/tasks" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001"
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001'}
data = None
request = urllib.request.Request(base + "/wms/v1/tasks", data=data, headers=headers, method="GET")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/wms/v1/tasks"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.GET();
var request = builder.build();
// No send in the offline example.
View sample response · 200
Static data; no request was sent.
{
"items": [
{
"id": "DEMO-TASK",
"status": "CREATED",
"version": 1
}
],
"nextCursor": "DEMO-NEXT"
}
400 · 401 · 403 · 429 · 503 → application/problem+json
Use contracted page limits and cursors; an invalid cursor requires
restarting the query, not assuming no tasks remain.
Error conditions and response
For listWmsTasks: 401/403 require identity, scope and site
checks; retries cannot bypass authority. Missing resources
require identifier and scope checks; absence does not prove
mission failure.
Create a warehouse task
createWmsTask · WMS · task:create
Sample request body
{
"taskType": "TRANSFER",
"siteId": "DEMO-SITE",
"warehouseId": "DEMO-WH",
"sourceLocationId": "DEMO-A",
"targetLocationId": "DEMO-B",
"lines": [
{
"skuId": "DEMO-SKU",
"quantity": 1,
"uom": "EA"
}
],
"executionMode": "AMR"
}
Source DTO: TRANSFER/PICK require sourceLocationId;
PUTAWAY/TRANSFER/REPLENISH require targetLocationId. siteId must
match permitted context. Domain services enforce conditional
rules.
TaskRequest · schema
Task · schema
cURL
Copy
curl --request POST \
"https://factoryflow-api.example.invalid/wms/v1/tasks" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001" \
--header "X-Idempotency-Key: DEMO-KEY" \
--header "Content-Type: application/json" \
--data-binary @request.json
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001', 'X-Idempotency-Key': 'DEMO-KEY', 'Content-Type': 'application/json'}
data = json.dumps({'taskType': 'TRANSFER', 'siteId': 'DEMO-SITE', 'warehouseId': 'DEMO-WH', 'sourceLocationId': 'DEMO-A', 'targetLocationId': 'DEMO-B', 'lines': [{'skuId': 'DEMO-SKU', 'quantity': 1, 'uom': 'EA'}], 'executionMode': 'AMR'}).encode("utf-8")
request = urllib.request.Request(base + "/wms/v1/tasks", data=data, headers=headers, method="POST")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/wms/v1/tasks"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.header("Content-Type", "application/json")
.header("X-Idempotency-Key", "DEMO-KEY")
.POST(java.net.http.HttpRequest.BodyPublishers.ofFile(java.nio.file.Path.of("request.json")));
var request = builder.build();
// No send in the offline example.
View sample response · 201
Static data; no request was sent.
{
"id": "DEMO-TASK",
"status": "CREATED",
"version": 1
}
400 · 401 · 403 · 429 · 503 · 409 · 422 → application/problem+json
TRANSFER without source or destination is blocked; correct SKU/UOM
mapping before creation.
Error conditions and response
For createWmsTask: 401/403 require identity, scope and site
checks; retries cannot bypass authority. Writes retain key/body
on retry; different bodies need a new intent after
reconciliation.
GET /wms/v1/tasks/{taskId}#
Read a warehouse task
getWmsTask · WMS · task:read
Task · schema
cURL
Copy
curl --request GET \
"https://factoryflow-api.example.invalid/wms/v1/tasks/DEMO-ID" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001"
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001'}
data = None
request = urllib.request.Request(base + "/wms/v1/tasks/DEMO-ID", data=data, headers=headers, method="GET")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/wms/v1/tasks/DEMO-ID"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.GET();
var request = builder.build();
// No send in the offline example.
View sample response · 200
Static data; no request was sent.
{
"id": "DEMO-TASK",
"status": "IN_PROGRESS",
"version": 3
}
400 · 401 · 403 · 429 · 503 · 404 → application/problem+json
Check task site authority; interpret COMPLETED within the WMS
domain.
Error conditions and response
For getWmsTask: 401/403 require identity, scope and site checks;
retries cannot bypass authority. Missing resources require
identifier and scope checks; absence does not prove mission
failure.
POST /wms/v1/tasks/{taskId}/confirm#
Confirm the business outcome
confirmWmsTask · WMS · task:execute
Example context: {"beforeStatus": "IN_PROGRESS", "beforeVersion":
3, "afterStatus": "COMPLETED", "afterVersion": 4, "condition":
"Valid scan evidence and matching object/site authority"}
Sample request body
{
"confirmationType": "SCAN",
"expectedVersion": 3,
"evidenceRef": "DEMO-SCAN"
}
Confirmation · schema
Task · schema
cURL
Copy
curl --request POST \
"https://factoryflow-api.example.invalid/wms/v1/tasks/DEMO-ID/confirm" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001" \
--header "X-Idempotency-Key: DEMO-KEY" \
--header "Content-Type: application/json" \
--data-binary @request.json
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001', 'X-Idempotency-Key': 'DEMO-KEY', 'Content-Type': 'application/json'}
data = json.dumps({'confirmationType': 'SCAN', 'expectedVersion': 3, 'evidenceRef': 'DEMO-SCAN'}).encode("utf-8")
request = urllib.request.Request(base + "/wms/v1/tasks/DEMO-ID/confirm", data=data, headers=headers, method="POST")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/wms/v1/tasks/DEMO-ID/confirm"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.header("Content-Type", "application/json")
.header("X-Idempotency-Key", "DEMO-KEY")
.POST(java.net.http.HttpRequest.BodyPublishers.ofFile(java.nio.file.Path.of("request.json")));
var request = builder.build();
// No send in the offline example.
View sample response · 200
Static data; no request was sent.
{
"id": "DEMO-TASK",
"status": "COMPLETED",
"version": 4
}
400 · 401 · 403 · 429 · 503 · 404 · 409 · 422 →
application/problem+json
Missing scans or stale expectedVersion block confirmation; reread
the task and verify evidence.
Error conditions and response
For confirmWmsTask: 401/403 require identity, scope and site
checks; retries cannot bypass authority. Writes retain key/body
on retry; different bodies need a new intent after
reconciliation.
POST /wcs/v1/execution-orders#
Create an execution order
createExecutionOrder · WCS ·
wcs:dispatch
Sample request body
{
"taskId": "DEMO-TASK",
"expectedTaskVersion": 2,
"routeRef": "DEMO-ROUTE"
}
ExecutionRequest · schema
Execution · schema
cURL
Copy
curl --request POST \
"https://factoryflow-api.example.invalid/wcs/v1/execution-orders" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001" \
--header "X-Idempotency-Key: DEMO-KEY" \
--header "Content-Type: application/json" \
--data-binary @request.json
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001', 'X-Idempotency-Key': 'DEMO-KEY', 'Content-Type': 'application/json'}
data = json.dumps({'taskId': 'DEMO-TASK', 'expectedTaskVersion': 2, 'routeRef': 'DEMO-ROUTE'}).encode("utf-8")
request = urllib.request.Request(base + "/wcs/v1/execution-orders", data=data, headers=headers, method="POST")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/wcs/v1/execution-orders"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.header("Content-Type", "application/json")
.header("X-Idempotency-Key", "DEMO-KEY")
.POST(java.net.http.HttpRequest.BodyPublishers.ofFile(java.nio.file.Path.of("request.json")));
var request = builder.build();
// No send in the offline example.
View sample response · 201
Static data; no request was sent.
{
"id": "DEMO-EXE",
"taskId": "DEMO-TASK",
"status": "CREATED",
"version": 1
}
400 · 401 · 403 · 429 · 503 · 409 · 422 → application/problem+json
Unreleased or revision-mismatched tasks hold the request for WMS
resolution.
Error conditions and response
For createExecutionOrder: 401/403 require identity, scope and
site checks; retries cannot bypass authority. Writes retain
key/body on retry; different bodies need a new intent after
reconciliation.
POST /wcs/v1/execution-orders/{orderId}/dispatch#
Dispatch execution
dispatchExecutionOrder · WCS ·
wcs:dispatch
Example context: {"beforeStatus": "PLANNED", "beforeVersion": 2,
"afterStatus": "DISPATCHING", "afterVersion": 3, "condition":
"Approved route, available executor and permissive safety"}
Sample request body
{
"expectedVersion": 2,
"executorRef": "DEMO-EXECUTOR",
"policyRef": "DEMO-POLICY"
}
DispatchRequest · schema
Execution · schema
cURL
Copy
curl --request POST \
"https://factoryflow-api.example.invalid/wcs/v1/execution-orders/DEMO-ID/dispatch" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001" \
--header "X-Idempotency-Key: DEMO-KEY" \
--header "Content-Type: application/json" \
--data-binary @request.json
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001', 'X-Idempotency-Key': 'DEMO-KEY', 'Content-Type': 'application/json'}
data = json.dumps({'expectedVersion': 2, 'executorRef': 'DEMO-EXECUTOR', 'policyRef': 'DEMO-POLICY'}).encode("utf-8")
request = urllib.request.Request(base + "/wcs/v1/execution-orders/DEMO-ID/dispatch", data=data, headers=headers, method="POST")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/wcs/v1/execution-orders/DEMO-ID/dispatch"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.header("Content-Type", "application/json")
.header("X-Idempotency-Key", "DEMO-KEY")
.POST(java.net.http.HttpRequest.BodyPublishers.ofFile(java.nio.file.Path.of("request.json")));
var request = builder.build();
// No send in the offline example.
View sample response · 202
Static data; no request was sent.
{
"id": "DEMO-EXE",
"taskId": "DEMO-TASK",
"status": "DISPATCHING",
"version": 3
}
400 · 401 · 403 · 429 · 503 · 404 · 409 · 422 →
application/problem+json
Wrong route, unavailable executor or failed safety holds dispatch;
202 is not completion.
Error conditions and response
For dispatchExecutionOrder: 401/403 require identity, scope and
site checks; retries cannot bypass authority. Writes retain
key/body on retry; different bodies need a new intent after
reconciliation.
GET /wcs/v1/execution-orders/{orderId}#
Reconcile execution
getExecutionOrder · WCS · wcs:read
Execution · schema
cURL
Copy
curl --request GET \
"https://factoryflow-api.example.invalid/wcs/v1/execution-orders/DEMO-ID" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001"
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001'}
data = None
request = urllib.request.Request(base + "/wcs/v1/execution-orders/DEMO-ID", data=data, headers=headers, method="GET")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/wcs/v1/execution-orders/DEMO-ID"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.GET();
var request = builder.build();
// No send in the offline example.
View sample response · 200
Static data; no request was sent.
{
"id": "DEMO-EXE",
"taskId": "DEMO-TASK",
"status": "EXECUTING",
"version": 4
}
400 · 401 · 403 · 429 · 503 · 404 → application/problem+json
For UNKNOWN, inspect mission/controller and callbacks rather than
infer FAILED.
Error conditions and response
For getExecutionOrder: 401/403 require identity, scope and site
checks; retries cannot bypass authority. Missing resources
require identifier and scope checks; absence does not prove
mission failure.
Create a mobile mission
createMission · Fleet · fleet:manage
Sample request body
{
"executionId": "DEMO-EXE",
"pickupPoint": "DEMO-A",
"dropoffPoint": "DEMO-B",
"fleetProfile": "DEMO-FLEET"
}
MissionRequest · schema
Mission · schema
cURL
Copy
curl --request POST \
"https://factoryflow-api.example.invalid/fleet/v1/missions" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001" \
--header "X-Idempotency-Key: DEMO-KEY" \
--header "Content-Type: application/json" \
--data-binary @request.json
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001', 'X-Idempotency-Key': 'DEMO-KEY', 'Content-Type': 'application/json'}
data = json.dumps({'executionId': 'DEMO-EXE', 'pickupPoint': 'DEMO-A', 'dropoffPoint': 'DEMO-B', 'fleetProfile': 'DEMO-FLEET'}).encode("utf-8")
request = urllib.request.Request(base + "/fleet/v1/missions", data=data, headers=headers, method="POST")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/fleet/v1/missions"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.header("Content-Type", "application/json")
.header("X-Idempotency-Key", "DEMO-KEY")
.POST(java.net.http.HttpRequest.BodyPublishers.ofFile(java.nio.file.Path.of("request.json")));
var request = builder.build();
// No send in the offline example.
View sample response · 201
Static data; no request was sent.
{
"id": "DEMO-MISSION",
"status": "CREATED"
}
400 · 401 · 403 · 429 · 503 · 409 · 422 → application/problem+json
If execution already has a mission, reconcile the existing ID
rather than recreate after a lost response.
Error conditions and response
For createMission: 401/403 require identity, scope and site
checks; retries cannot bypass authority. Writes retain key/body
on retry; different bodies need a new intent after
reconciliation.
GET /fleet/v1/missions/{missionId}#
Read a mission
getMission · Fleet · fleet:read
Mission · schema
cURL
Copy
curl --request GET \
"https://factoryflow-api.example.invalid/fleet/v1/missions/DEMO-ID" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001"
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001'}
data = None
request = urllib.request.Request(base + "/fleet/v1/missions/DEMO-ID", data=data, headers=headers, method="GET")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/fleet/v1/missions/DEMO-ID"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.GET();
var request = builder.build();
// No send in the offline example.
View sample response · 200
Static data; no request was sent.
{
"id": "DEMO-MISSION",
"status": "CREATED"
}
400 · 401 · 403 · 429 · 503 · 404 → application/problem+json
Missing IDs may indicate profile or mapping issues; inspect the
source fleet before another mission.
Error conditions and response
For getMission: 401/403 require identity, scope and site checks;
retries cannot bypass authority. Missing resources require
identifier and scope checks; absence does not prove mission
failure.
POST /robot-cell/v1/cell-jobs#
Create a cell job
createCellJob · Cell ·
robot-cell:operate
Sample request body
{
"executionId": "DEMO-EXE",
"cellId": "DEMO-CELL",
"recipeId": "DEMO-RECIPE",
"recipeVersion": "1"
}
CellRequest · schema
CellJob · schema
cURL
Copy
curl --request POST \
"https://factoryflow-api.example.invalid/robot-cell/v1/cell-jobs" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001" \
--header "X-Idempotency-Key: DEMO-KEY" \
--header "Content-Type: application/json" \
--data-binary @request.json
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001', 'X-Idempotency-Key': 'DEMO-KEY', 'Content-Type': 'application/json'}
data = json.dumps({'executionId': 'DEMO-EXE', 'cellId': 'DEMO-CELL', 'recipeId': 'DEMO-RECIPE', 'recipeVersion': '1'}).encode("utf-8")
request = urllib.request.Request(base + "/robot-cell/v1/cell-jobs", data=data, headers=headers, method="POST")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/robot-cell/v1/cell-jobs"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.header("Content-Type", "application/json")
.header("X-Idempotency-Key", "DEMO-KEY")
.POST(java.net.http.HttpRequest.BodyPublishers.ofFile(java.nio.file.Path.of("request.json")));
var request = builder.build();
// No send in the offline example.
View sample response · 201
Static data; no request was sent.
{
"id": "DEMO-JOB",
"status": "CREATED",
"recipeVersion": "1"
}
400 · 401 · 403 · 429 · 503 · 409 · 422 → application/problem+json
Recipe/program mismatch or unready cell blocks the job; the cell
engineer checks revision and mode.
Error conditions and response
For createCellJob: 401/403 require identity, scope and site
checks; retries cannot bypass authority. Writes retain key/body
on retry; different bodies need a new intent after
reconciliation.
POST /devices/v1/devices/{deviceId}/commands#
Submit a device command intent
createDeviceCommand · Device ·
device:command
Sample request body
{
"commandType": "START_JOB",
"expectedVersion": 1,
"policyRef": "DEMO-POLICY"
}
CommandRequest · schema
Command · schema
cURL
Copy
curl --request POST \
"https://factoryflow-api.example.invalid/devices/v1/devices/DEMO-ID/commands" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001" \
--header "X-Idempotency-Key: DEMO-KEY" \
--header "Content-Type: application/json" \
--data-binary @request.json
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001', 'X-Idempotency-Key': 'DEMO-KEY', 'Content-Type': 'application/json'}
data = json.dumps({'commandType': 'START_JOB', 'expectedVersion': 1, 'policyRef': 'DEMO-POLICY'}).encode("utf-8")
request = urllib.request.Request(base + "/devices/v1/devices/DEMO-ID/commands", data=data, headers=headers, method="POST")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/devices/v1/devices/DEMO-ID/commands"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.header("Content-Type", "application/json")
.header("X-Idempotency-Key", "DEMO-KEY")
.POST(java.net.http.HttpRequest.BodyPublishers.ofFile(java.nio.file.Path.of("request.json")));
var request = builder.build();
// No send in the offline example.
View sample response · 202
Static data; no request was sent.
{
"id": "DEMO-COMMAND",
"status": "CREATED"
}
400 · 401 · 403 · 429 · 503 · 404 · 409 · 422 →
application/problem+json
Reject non-allowlisted commands or failed interlocks; no
substitute raw command.
Error conditions and response
For createDeviceCommand: 401/403 require identity, scope and
site checks; retries cannot bypass authority. Writes retain
key/body on retry; different bodies need a new intent after
reconciliation.
POST /device-callback/v1/fleet-events#
Receive a fleet callback
receiveFleetEvent · Callback ·
fleet:event
Sample request body
{
"eventId": "DEMO-EVENT",
"correlationId": "00000000-0000-4000-8000-000000000001",
"entityId": "DEMO-MISSION",
"entityVersion": 9,
"eventType": "mission.status.changed",
"occurredAt": "2026-10-26T00:00:00Z",
"schemaVersion": "1.0",
"source": "DEMO-FLEET-ADAPTER",
"payload": {
"status": "COMPLETED",
"executionId": "DEMO-EXE"
}
}
Callback · schema
Receipt · schema
cURL
Copy
curl --request POST \
"https://factoryflow-api.example.invalid/device-callback/v1/fleet-events" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001" \
--header "X-Idempotency-Key: DEMO-KEY" \
--header "Content-Type: application/json" \
--data-binary @request.json
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001', 'X-Idempotency-Key': 'DEMO-KEY', 'Content-Type': 'application/json'}
data = json.dumps({'eventId': 'DEMO-EVENT', 'correlationId': '00000000-0000-4000-8000-000000000001', 'entityId': 'DEMO-MISSION', 'entityVersion': 9, 'eventType': 'mission.status.changed', 'occurredAt': '2026-10-26T00:00:00Z', 'schemaVersion': '1.0', 'source': 'DEMO-FLEET-ADAPTER', 'payload': {'status': 'COMPLETED', 'executionId': 'DEMO-EXE'}}).encode("utf-8")
request = urllib.request.Request(base + "/device-callback/v1/fleet-events", data=data, headers=headers, method="POST")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/device-callback/v1/fleet-events"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.header("Content-Type", "application/json")
.header("X-Idempotency-Key", "DEMO-KEY")
.POST(java.net.http.HttpRequest.BodyPublishers.ofFile(java.nio.file.Path.of("request.json")));
var request = builder.build();
// No send in the offline example.
View sample response · 202
Static data; no request was sent.
{
"id": "DEMO-RECEIPT",
"status": "RECEIVED"
}
400 · 401 · 403 · 429 · 503 · 409 · 422 → application/problem+json
Deduplicate eventId; reconcile stale entityVersion under contract
without regressing state.
Error conditions and response
For receiveFleetEvent: 401/403 require identity, scope and site
checks; retries cannot bypass authority. Writes retain key/body
on retry; different bodies need a new intent after
reconciliation.
POST /exceptions/v1/exceptions#
Raise an operational exception
raiseException · Exception ·
exception:create
Sample request body
{
"entityId": "DEMO-MISSION",
"reasonCode": "DEMO_TIMEOUT",
"evidenceRef": "DEMO-TRACE",
"ownerRef": "DEMO-OWNER"
}
ExceptionRequest · schema
Exception · schema
cURL
Copy
curl --request POST \
"https://factoryflow-api.example.invalid/exceptions/v1/exceptions" \
--header "Authorization: Bearer ${FACTORYFLOW_ACCESS_TOKEN}" \
--header "X-Tenant-Id: DEMO-TENANT" \
--header "X-Site-Id: DEMO-SITE" \
--header "X-Correlation-Id: 00000000-0000-4000-8000-000000000001" \
--header "X-Idempotency-Key: DEMO-KEY" \
--header "Content-Type: application/json" \
--data-binary @request.json
Python
Copy
import json, os, urllib.request
base = "https://factoryflow-api.example.invalid"
headers = {'Authorization': 'Bearer ' + os.environ['FACTORYFLOW_ACCESS_TOKEN'], 'X-Tenant-Id': 'DEMO-TENANT', 'X-Site-Id': 'DEMO-SITE', 'X-Correlation-Id': '00000000-0000-4000-8000-000000000001', 'X-Idempotency-Key': 'DEMO-KEY', 'Content-Type': 'application/json'}
data = json.dumps({'entityId': 'DEMO-MISSION', 'reasonCode': 'DEMO_TIMEOUT', 'evidenceRef': 'DEMO-TRACE', 'ownerRef': 'DEMO-OWNER'}).encode("utf-8")
request = urllib.request.Request(base + "/exceptions/v1/exceptions", data=data, headers=headers, method="POST")
# No request is sent by this offline example.
Java
Copy
var builder = java.net.http.HttpRequest.newBuilder(java.net.URI.create("https://factoryflow-api.example.invalid/exceptions/v1/exceptions"))
.header("Authorization", "Bearer " + System.getenv("FACTORYFLOW_ACCESS_TOKEN"))
.header("X-Tenant-Id", "DEMO-TENANT")
.header("X-Site-Id", "DEMO-SITE")
.header("X-Correlation-Id", "00000000-0000-4000-8000-000000000001")
.header("Content-Type", "application/json")
.header("X-Idempotency-Key", "DEMO-KEY")
.POST(java.net.http.HttpRequest.BodyPublishers.ofFile(java.nio.file.Path.of("request.json")));
var request = builder.build();
// No send in the offline example.
View sample response · 201
Static data; no request was sent.
{
"id": "DEMO-EXCEPTION",
"status": "CREATED"
}
400 · 401 · 403 · 429 · 503 · 409 · 422 → application/problem+json
reasonCode and object require sufficient context; assign a
resolver when physical outcomes remain unclear.
Error conditions and response
For raiseException: 401/403 require identity, scope and site
checks; retries cannot bypass authority. Writes retain key/body
on retry; different bodies need a new intent after
reconciliation.