The console is a client.
The API is the product.
Everything Titan Command Center's console does — fleet view, missions, teleop, OTA, audit — it does through this API. It's openly specified: an OpenAPI 3.1 document plus a JSON Schema for every wire message, so integrators build against the same contract the console ships on.
Poll the fleet.
Stream the mission.
A deliberately small HTTP surface for state, and a WebSocket for everything live — commands down, telemetry and video up. Auth is bearer-token (JWT-verified in production); browsers pass the token in the URL because the WebSocket constructor can't set headers.
REST
GET /fleetThe live fleet snapshot: units (type, owner vs operator, capabilities, service status, mission, realm field|matrix), base stations, connected operatorsGET /ota/jobsRollout state: jobs, cohorts, health gates, audit tailGET /healthLiveness and counters — devices, operators, anchors, fleet mission stateWebSocket
WS /v0/operator/{id}The operator socket — Bearer or ?token= auth, JWT-verified when configured→ mission · motor_override · device_estopCommand down: mission control, teleop override, emergency stop→ ota_advance_cohort · ota_pause · ota_resume · ota_rollbackRollout control from any authorized client← video_frame · ota_state · safe_zoneLive sensor feeds, rollout state pushes, fleet safe-zone setWS /v0/{deviceId}The machine socket — where Titan Core OS endpoints connectSix services.
One authority model.
Behind the wire surface sits the control plane. Every mutating call passes the same two gates: an RBAC permission check, and a hash-chained audit entry attributed to a named operator.
Fleet & Telemetry
registry.enroll(claimToken, robotId, formFactor)Claim-token device enrollment; identity signed at the doortelemetry.ingest(envelope) → Alert[]Telemetry in, threshold alerts out — acknowledge and resolve by idMissions
missions.create(operator, mission)Vertical templates or custom missions — RBAC-checked, auditedmissions.transition(operator, id, state)The mission state machine is API-driven; the console is just a clientOTA Rollouts
ota.create(operator, artifacts, cohorts)Staged cohort rollouts with health gatesota.runCohort / pause / resume / rollbackEvery action attributed to a named operator and hash-chain auditedAccess & Authority
rbac.can(operator, permission) / assert(...)Role-based permission checks on every mutating call — no bypass pathteleop.request / assign / handoff / closeTeleop sessions are brokered, never grabbedAudit & Evidence
audit.list() / verify()The hash chain is queryable and verifiable end to endaudit.exportWormBatch(bucketUri)Write-once evidence export for compliance programsInterop
vda5050.translate(message)Third-party AGV fleets speak VDA 5050 to the same control planedeconfliction (Open-RMF-style)Mixed fleets negotiate space through the platform, not each otherOpenly specified: the API ships as an OpenAPI 3.1 document plus a JSON Schema for every wire message — fleet snapshots, mission intents, overrides, OTA manifests, resync frames — with validated examples. The machine side of the conversation (the Core Command Link) is specified on the same policy; between the two documents, every byte between console, control plane, and machine has a published contract. Versioned with the platform; additive within a major.