This document defines the MVP HTTP contract for the workerfleet monitoring service.
Base path: /v1
Worker ingress auth:
POST /v1/workers/registerandPOST /v1/workers/heartbeatrequireAuthorization: Bearer <token>whenWORKERFLEET_WORKER_AUTH_TOKENis configured.- Missing, malformed, or invalid credentials return
401with a generic authentication error and do not echo credential values. WORKERFLEET_PROFILE=prodrequiresWORKERFLEET_WORKER_AUTH_TOKENat startup, so production ingress fails closed by default.
Query API auth:
- Query endpoints require
Authorization: Bearer <token>whenWORKERFLEET_ADMIN_AUTH_TOKENis configured and query auth is required. WORKERFLEET_QUERY_AUTH_REQUIRED=truerequires an admin token outside production;WORKERFLEET_PROFILE=prodrequiresWORKERFLEET_ADMIN_AUTH_TOKENat startup.- Worker ingress auth and query API auth are separate credentials. A worker token cannot list workers, tasks, alerts, or fleet summaries.
/healthz,/readyz, and/metricsare not covered by query API auth in this reference app.
Registers or refreshes worker identity.
Request body:
{
"worker_id": "worker-1",
"namespace": "sim",
"pod_name": "worker-1",
"pod_uid": "pod-uid-1",
"node_name": "node-a",
"container_name": "worker",
"image": "worker:1.0.0",
"version": "1.0.0",
"observed_at": "2026-04-19T10:00:00Z"
}Success response:
{
"data": {
"worker_id": "worker-1",
"status": "unknown",
"registered_at": "2026-04-19T10:00:00Z"
}
}Reports worker liveness, readiness, and the full active-task set.
Request body:
{
"worker_id": "worker-1",
"process_alive": true,
"accepting_tasks": false,
"observed_at": "2026-04-19T10:01:00Z",
"last_error": "",
"active_tasks": [
{
"task_id": "task-1",
"exec_plan_id": "plan-20260419-001",
"task_type": "simulation",
"phase": "running",
"phase_name": "running",
"current_step": {
"step": "simulate",
"step_name": "simulation",
"status": "running",
"started_at": "2026-04-19T10:00:30Z",
"updated_at": "2026-04-19T10:01:00Z",
"attempt": 1,
"error_class": ""
}
},
{
"task_id": "task-2",
"exec_plan_id": "plan-20260419-001",
"task_type": "simulation",
"phase": "preparing",
"phase_name": "warming",
"current_step": {
"step": "download_bundle",
"step_name": "download bundle",
"status": "running",
"started_at": "2026-04-19T10:00:55Z",
"updated_at": "2026-04-19T10:01:00Z",
"attempt": 1
}
}
]
}Notes:
active_tasksis a full-set replacement, not a delta stream.task_ididentifies one case.exec_plan_idgroups cases under one simulation execution plan.current_stepreports the case step currently being processed. Omit it for legacy workers that cannot report step state.current_step.stepshould come from a controlled worker-side enum such asprepare_env,download_bundle,download_data,convert_data,simulate,upload_result, orcleanup_env.current_step.statusshould be one ofrunning,succeeded,failed,canceled, orskipped; unknown values are normalized tounknown.current_step.error_classmust be low-cardinality, for exampleobject_store_timeoutordependency_missing, not a raw exception message.process_aliveandaccepting_tasksare distinct.accepting_tasks=falsewith active tasks means the worker is busy, not necessarily offline.
Success response:
{
"data": {
"worker_id": "worker-1",
"status": "online",
"status_reason": "busy",
"observed_at": "2026-04-19T10:01:00Z",
"active_task_count": 2
}
}Lists workers with optional filters.
Query parameters:
statusnamespacenode_nametask_typeaccepting_taskspagepage_size
Success response:
{
"data": {
"items": [
{
"worker_id": "worker-1",
"namespace": "sim",
"pod_name": "worker-1",
"node_name": "node-a",
"status": "online",
"status_reason": "busy",
"process_alive": true,
"accepting_tasks": false,
"last_seen_at": "2026-04-19T10:01:00Z",
"active_task_count": 2,
"active_tasks": [
{
"task_id": "task-1",
"exec_plan_id": "plan-20260419-001",
"task_type": "simulation",
"phase": "running",
"phase_name": "running",
"current_step": {
"step": "simulate",
"step_name": "simulation",
"status": "running",
"started_at": "2026-04-19T10:00:30Z",
"updated_at": "2026-04-19T10:01:00Z",
"attempt": 1
}
}
]
}
],
"page": 1,
"page_size": 50,
"total": 1
}
}Returns one worker with current active tasks and readiness state.
Returns the current or most recent task view for a task ID.
Example success payload:
{
"data": {
"task_id": "task-1",
"worker_id": "worker-1",
"exec_plan_id": "plan-20260419-001",
"task_type": "simulation",
"phase": "running",
"phase_name": "running",
"current_step": {
"step": "simulate",
"step_name": "simulation",
"status": "running",
"started_at": "2026-04-19T10:00:30Z",
"updated_at": "2026-04-19T10:01:00Z",
"attempt": 1
},
"status": "active",
"started_at": "2026-04-19T10:00:30Z",
"updated_at": "2026-04-19T10:01:00Z"
}
}Notes:
- Query responses reuse the same read-model contract across worker detail, task detail, case timeline, and exec-plan drilldown payloads.
current_stepis omitted from query responses when the worker does not currently report a step.
Returns case step transition and completion history for one case.
Example success payload:
{
"data": {
"task_id": "task-1",
"items": [
{
"task_id": "task-1",
"worker_id": "worker-1",
"exec_plan_id": "plan-20260419-001",
"namespace": "sim",
"pod_name": "worker-1",
"node_name": "node-a",
"step": "download_bundle",
"step_name": "download bundle",
"status": "succeeded",
"result": "succeeded",
"attempt": 1,
"started_at": "2026-04-19T10:00:10Z",
"finished_at": "2026-04-19T10:00:30Z",
"observed_at": "2026-04-19T10:00:30Z",
"event_type": "task_step_finished"
}
]
}
}Returns paginated case step records for drilldown from Grafana aggregate panels.
Query parameters:
node_namepod_namesteppagepage_size
Example success payload:
{
"data": {
"exec_plan_id": "plan-20260419-001",
"items": [
{
"task_id": "task-1",
"worker_id": "worker-1",
"exec_plan_id": "plan-20260419-001",
"pod_name": "worker-1",
"node_name": "node-a",
"step": "simulate",
"status": "failed",
"result": "failed",
"error_class": "simulation_timeout",
"observed_at": "2026-04-19T10:05:00Z"
}
],
"page": 1,
"page_size": 50,
"total": 1
}
}Returns fleet totals for workers and active tasks.
Lists alert records.
Query parameters:
worker_idalert_typestatuspagepage_size
Errors use the standard contract.WriteError envelope.
- Invalid JSON:
INVALID_JSON - Invalid query parameter:
INVALID_QUERY - Missing required field:
REQUIRED_FIELD_MISSING - Resource not found:
RESOURCE_NOT_FOUND