API Reference REST + JSON

Platform API Reference

Complete REST API reference for CenterOS. 39 actions across 9 categories, all discoverable via a single endpoint.

Updated Apr 2026 39 actions JWT + PAT auth

Base URL

All API endpoints are relative to the production backend:

https://fearless-backend-533466225971.us-central1.run.app

For local development, the Vite dev server proxies /api to localhost:8000 automatically. You can also use the CENTEROS_API_URL environment variable to override the base URL in the CLI and MCP server.

Authentication

The API supports two authentication methods. All authenticated endpoints require a Bearer token in the Authorization header.

JWT (Session Token)

Obtained by logging in with username and password. Short-lived, suitable for interactive sessions.

shell
# Login and get a JWT
$ curl -X POST https://fearless-backend-533466225971.us-central1.run.app/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username": "jerry", "password": "***"}'

# Response includes: {"access_token": "eyJ...", "user": {...}}

PAT (Personal Access Token)

Long-lived tokens for CI/CD pipelines, scripts, and agent workflows. PAT tokens start with the frl_ prefix. Create one via the CLI or the platform dashboard.

shell
# Create a PAT via CLI
$ centeros pat create --name "my-agent" --scopes "*"
# PAT created: frl_abc123...

# Use the PAT in API calls
$ curl https://fearless-backend-533466225971.us-central1.run.app/api/actions \
  -H "Authorization: Bearer frl_abc123..."
Scoped tokens: PATs can be scoped to specific permissions (e.g. datasets:read,training:write). Use * for full access. The API filters visible actions based on your token's scopes.

Health Check

shell
$ curl https://fearless-backend-533466225971.us-central1.run.app/api/health

# {"status": "ok", "version": "...", "database": "ok"}

No authentication required. Returns 200 when the backend is healthy.

Action Layer

The Action Layer is the unified API surface shared by the platform UI, CLI, MCP server, and AI agents. All 39 actions are discoverable via two endpoints:

MethodEndpointDescription
GET/api/actionsList all available actions with input schemas. Optionally filter by ?category=datasets.
POST/api/actions/{name}Execute an action by name. Body: {"params": {...}}. Requires Bearer token.

Discover actions

shell
# List all actions (public — no auth needed for discovery)
$ curl https://fearless-backend-533466225971.us-central1.run.app/api/actions

# Filter by category
$ curl "https://fearless-backend-533466225971.us-central1.run.app/api/actions?category=training"

Execute an action

shell
$ curl -X POST https://fearless-backend-533466225971.us-central1.run.app/api/actions/list_datasets \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {"limit": 10}}'

# {"ok": true, "data": [...]}

Datasets

Manage robotics datasets — list, get details, upload, and delete. Scopes: datasets:read datasets:write

ActionDescriptionRequired ParamsScope
list_datasetsList datasets with optional search, file type, and pagination filters.Nonedatasets:read
get_datasetGet detailed information about a single dataset.dataset_iddatasets:read
delete_datasetDelete a dataset and its associated file from storage.dataset_iddatasets:write
upload_datasetCreate a dataset record (metadata). For file upload, use get_upload_signed_url.namedatasets:write
get_upload_signed_urlGenerate a GCS signed URL for direct-to-cloud dataset upload.filename, file_sizedatasets:write
confirm_uploadConfirm that a signed-URL upload completed. Marks the dataset as ready.dataset_iddatasets:write
shell
# List datasets with search filter
$ curl -X POST .../api/actions/list_datasets \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {"search": "grasp", "file_type": "hdf5", "limit": 20}}'

# Upload flow: get signed URL, upload file, confirm
$ curl -X POST .../api/actions/get_upload_signed_url \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {"filename": "episode_001.hdf5", "file_size": 52428800}}'

Training

Create and manage training and fine-tuning jobs. Scopes: training:read training:write

ActionDescriptionRequired ParamsScope
list_training_jobsList training jobs with optional status and model type filters.Nonetraining:read
create_training_jobCreate a new training or fine-tuning job from one or more datasets.dataset_idstraining:write
get_training_statusGet the current status and details of a training job.job_idtraining:read
launch_trainingLaunch a pending training job (transition to running).job_idtraining:write
get_finetune_catalogList all supported fine-tuning base model providers and models.Nonetraining:read
estimate_costEstimate the cost of a training run based on datasets and infra.Nonetraining:read
shell
# Create a training job
$ curl -X POST .../api/actions/create_training_job \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {"name": "dp-v1", "model_type": "diffusion_policy", "dataset_ids": [1, 2], "mode": "finetune"}}'

# Launch a pending job
$ curl -X POST .../api/actions/launch_training \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {"job_id": "abc123def456"}}'

Models

Model registry with lifecycle management. Scopes: models:read models:write

ActionDescriptionRequired ParamsScope
list_modelsList model versions with optional status and name filters.Nonemodels:read
register_modelRegister a new model version in the model registry.namemodels:write
promote_modelPromote a model through lifecycle stages: draft → validated → deployed → retired.model_id, target_statusmodels:write
get_model_lineageGet full lineage: training job, datasets, deployments, evaluations.model_idmodels:read
shell
# Register a model from a training run
$ curl -X POST .../api/actions/register_model \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {"name": "dp-v1", "artifact_uri": "gs://bucket/model.pt", "training_job_id": "abc123"}}'

# Promote to validated
$ curl -X POST .../api/actions/promote_model \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {"model_id": 5, "target_status": "validated"}}'

Fleet

Robot fleet management, deployment, and safety commands. Scopes: fleet:read fleet:write

ActionDescriptionRequired ParamsScope
get_fleet_summaryHigh-level fleet summary: counts by status, alerts, tickets.Nonefleet:read
list_robotsList robots with optional status, site, and search filters.Nonefleet:read
get_robot_stateDetailed state of a single robot: heartbeat, commands, alerts.robot_idfleet:read
register_robotRegister a new robot in the fleet.robot_idfleet:write
deploy_modelDeploy a validated model version to a specific robot.robot_id, model_version_idfleet:write models:read
emergency_stopSend an emergency stop (e-stop) command to a robot. Highest priority.robot_idfleet:write
shell
# Register a robot
$ curl -X POST .../api/actions/register_robot \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {"robot_id": "arm-01", "name": "Lab Arm 1", "robot_type": "arm"}}'

# Deploy a model to a robot
$ curl -X POST .../api/actions/deploy_model \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {"robot_id": "arm-01", "model_version_id": 5, "strategy": "immediate"}}'

# Emergency stop
$ curl -X POST .../api/actions/emergency_stop \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {"robot_id": "arm-01", "reason": "safety_check"}}'

Annotations

Data annotation task management and quality metrics. Scopes: annotations:read annotations:write

ActionDescriptionRequired ParamsScope
list_annotation_tasksList annotation tasks with optional status, assignee, and search filters.Noneannotations:read
create_annotation_taskCreate a new annotation task, optionally linked to a dataset.None (title recommended)annotations:write
get_annotation_metricsAggregated quality metrics: pass rate, review counts, status distribution.Noneannotations:read
submit_taskSubmit an annotation task for review (transition to in_review).task_idannotations:write
shell
# Create an annotation task
$ curl -X POST .../api/actions/create_annotation_task \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {"title": "Label grasp episodes", "dataset_id": 42, "data_type": "video", "priority": "high"}}'

Organizations

Organization and team membership management. Scopes: orgs:read orgs:write

ActionDescriptionRequired ParamsScope
list_orgsList organizations. Superadmins see all; others see only their org.Noneorgs:read
list_org_membersList members of an organization with their roles.None (org_id optional)orgs:read
invite_memberInvite a user to an organization. Creates the user if they do not exist.org_id, emailorgs:write

Stats

Platform-wide statistics and system health checks. Scope: stats:read

ActionDescriptionRequired ParamsScope
get_platform_statsAggregated platform statistics: dataset counts, training jobs, robots, annotations.Nonestats:read
get_system_healthCheck the health of backend systems: database, storage, overall status.Nonestats:read
shell
# Get platform stats
$ curl -X POST .../api/actions/get_platform_stats \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {}}'

# Check system health
$ curl -X POST .../api/actions/get_system_health \
  -H "Authorization: Bearer frl_..." \
  -H "Content-Type: application/json" \
  -d '{"params": {}}'

Error Codes

All action errors return a JSON body with {"ok": false, "detail": "..."} and the appropriate HTTP status code.

CodeMeaningCommon Cause
400Bad RequestMissing required parameter or invalid value.
401UnauthorizedMissing or invalid Bearer token.
403ForbiddenToken scopes do not include the required permission, or org isolation violation.
404Not FoundUnknown action name, or resource (dataset, model, robot) does not exist.
409ConflictDuplicate resource (e.g. robot already registered, user already a member).
413Payload Too LargeFile exceeds the maximum upload size.
500Internal Server ErrorUnhandled exception in the action handler.

Scopes Reference

Scopes control which actions a token can access. PATs can be created with specific scopes; JWTs derive scopes from the user's role.

ScopeActions Granted
datasets:readlist_datasets, get_dataset
datasets:writedelete_dataset, upload_dataset, get_upload_signed_url, confirm_upload
training:readlist_training_jobs, get_training_status, get_finetune_catalog, estimate_cost
training:writecreate_training_job, launch_training
models:readlist_models, get_model_lineage
models:writeregister_model, promote_model
fleet:readget_fleet_summary, list_robots, get_robot_state
fleet:writeregister_robot, deploy_model, emergency_stop
annotations:readlist_annotation_tasks, get_annotation_metrics
annotations:writecreate_annotation_task, submit_task
orgs:readlist_orgs, list_org_members
orgs:writeinvite_member
stats:readget_platform_stats, get_system_health
*All actions (wildcard)

Role-to-Scope Mapping

RoleScopes
adminAll scopes
operatordatasets:*, training:*, models:read, fleet:*, annotations:*, stats:read
annotatordatasets:read, annotations:*, stats:read
viewerAll :read scopes

Next steps