Scaleout Edge REST API
This section documents the server-side REST API exposed by the Scaleout Edge control plane. These endpoints are used by clients, combiners, and external integrations to interact with the Scaleout Edge network. The API includes operations for project management, training orchestration, model handling, metrics, telemetry, and system-level metadata.
Authentication and Control
Endpoints related to authentication, authorization, and high-level control of the federated network.
GET /api/v1/attributes/
Retrieve a paginated list of attributes.
Query parameters
key (str) — filter by attribute key
value (str) — filter by attribute value
sender.client_id (str) — filter by sender client ID
sender.combiner_id (str) — filter by sender combiner ID
Responses
200 OK
JSON object with keys: count (total number of matching attributes), result (list of attribute objects)
500 Internal Server Error
Unexpected error occurred while fetching attributes.
POST /api/v1/attributes/
Create a new attribute.
Request body
JSON or form-encoded object describing the attribute. The payload is validated and used to populate an attribute object.
Responses
201 Created
The created attribute object.
400 Bad Request
Validation or missing field errors.
500 Internal Server Error
Unexpected error occurred while creating the attribute.
GET /api/v1/attributes/{id}
Retrieve a single attribute by its identifier.
Path parameters
id (str) — attribute identifier.
Responses
200 OK
Attribute object.
404 Not Found
If no attribute exists with the given id.
500 Internal Server Error
Unexpected error occurred while fetching the attribute.
GET /api/v1/attributes/count
Get the number of attributes matching the given query parameters.
Query parameters
key (str) — filter by attribute key
value (str) — filter by attribute value
sender.client_id (str) — filter by sender client ID
sender.combiner_id (str) — filter by sender combiner ID
Responses
200 OK
Integer count of matching attributes.
500 Internal Server Error
Unexpected error occurred while counting attributes.
POST /api/v1/attributes/count
Get the number of attributes matching filters provided in the request body.
Request body
JSON or form-encoded object whose keys are used as filters on the attribute store.
Responses
200 OK
Integer count of matching attributes.
500 Internal Server Error
Unexpected error occurred while counting attributes.
POST /api/v1/attributes/current
Get current attributes for nodes (clients or combiners)
Request body
entity_ids (list) — List of entity IDs to retrieve attributes for
Responses
200 OK
A dict of entities and their attributes
{ ... }400 Bad Request
Missing required field
500 Internal Server Error
Unexpected error occurred while fetching current attributes.
POST /api/v1/attributes/list
Retrieve a paginated list of attributes using filters provided in the request body.
Request body
JSON or form-encoded object whose keys are used as filters on the attribute store.
Responses
200 OK
JSON object with keys: count (total number of matching attributes), result (list of attribute objects)
500 Internal Server Error
Unexpected error occurred while fetching attributes.
POST /api/v1/auth/token
Generate a new long-lived API token for CLI or programmatic access.
This endpoint is called with an existing authenticated JWT (forwarded in
the Authorization header). It
validates the incoming token, extracts user identity, and issues a new
API token with a configurable lifetime and role.
Headers
Authorization (str) —
Bearer <existing_jwt>used to authenticate the caller.
Request body
token_type (str) — Role to associate with the issued token (e.g.
"client"or"admin"). Default is"client".expires_in_days (int) — Token lifetime in days. Default is 365.
Responses
201 Created
Token successfully generated.
{ "token": "<jwt>", "expires_at": "<iso-8601 timestamp>", "token_type": "<role>" }401 Unauthorized
Missing or invalid
Authorizationheader, or invalid incoming JWT.500 Internal Server Error
Unexpected error occurred while generating the API token.
POST /api/v1/control/continue
Deprecated: Use POST /api/v1/commands/{id}/skip instead. This endpoint is
preserved for backward compatibility with clients predating version 1.1.
Send a SKIP signal to the controller.
Responses
200 OK
Sent continue signal.
{"message": "Sent continue signal"}500 Internal Server Error
Unexpected error occurred while sending the continue signal.
POST /api/v1/control/run_command
Run a custom command on the controller.
Commands must follow the "Custom_<Name>" naming scheme and may include
additional arbitrary parameters.
Request body
command_type (str) — The custom command type. Must NOT start with
"Fedn_". If it does not start with"Custom_", the prefix is added automatically.timeout (int, optional) — timeout in seconds for the command, -1 for infinite (default: 180)
paramA (str, optional) — string
paramB (int, optional) — integer
Examples
{ "command_type": "Custom_DoSomething", "paramA": "value1", "paramB": 123 }
Notes
command_typeis required.All other fields provided in the request body are passed as command parameters.
Responses
200 OK
If command is pending:
{"message": "Command Custom_X is pending", "correlation_id": "..."}If executed:
{"message": "Sent command: Custom_X"}400 Bad Request
Missing or forbidden
command_type500 Internal Server Error
Unexpected error occurred while sending the command.
POST /api/v1/control/skip
Send a SKIP signal to the controller. Used to skip the current synchronization barrier.
Responses
200 OK
Sent skip signal.
{"message": "Sent skip signal"}500 Internal Server Error
Unexpected error occurred while sending the skip signal.
POST /api/v1/control/start_inference
Start an inference session.
Request body
model_id (str) — ID of the model to use for inference
timeout (int, optional) — timeout in seconds for the inference session, -1 for infinite (default: 180)
Responses
200 OK
Inference session started successfully
400 Bad Request
Invalid request payload
500 Internal Server Error
Unexpected error occurred while starting the inference session.
POST /api/v1/control/start_session
Start a new training session.
This endpoint is exposed under the /control namespace for systems that operate the controller directly.
Request body
session_id (str) — ID of the session to start
rounds (int, optional) — number of rounds to run
round_timeout (int, optional) — per-round timeout in seconds
model_name_prefix (str, optional) — prefix for produced model names
client_ids (str, optional) — comma-separated list of specific client IDs to use
Responses
200 OK
session successfully started
400 Bad Request
invalid request payload
500 Internal Server Error
Unexpected error occurred while starting the session.
POST /api/v1/control/stop
Send a STOP signal to the controller, instructing it to halt any currently executing session.
Responses
200 OK
Sent stop signal.
{"message": "Sent stop signal"}500 Internal Server Error
Unexpected error occurred while sending the stop signal.
Clients and Combiners
Endpoints for managing clients, combiners, and their runtime state in the federated network.
GET /api/v1/clients/
Retrieve a filtered and paginated list of clients.
Supports query-based filtering and header-based pagination/sorting. Useful for listing clients in the controller UI or administrative scripts.
Query parameters
name (str) — Filter by client name
combiner (str) — Filter by assigned combiner ID
combiner_preferred (str) — Filter by preferred combiner ID
ip (str) — Filter by client IP
status (str) — Filter by client status
updated_at (str) — Filter by timestamp (string)
Headers
X-Limit (int) — Max number of results
X-Skip (int) — Number of results to skip
X-Sort-Key (str) — Field to sort by
X-Sort-Order (str) —
ascordesc
Responses
200 OK
{ "count": <int>, "result": [ { "client_id": "<string>", "name": "<string>", "ip": "<string>", "status": "<string>" }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching clients.
GET /api/v1/clients/{id}
Retrieve a single client by ID.
Path parameters
id (str) — Client ID
Responses
200 OK
Client object
404 Not Found
Client does not exist
500 Internal Server Error
Unexpected error occurred while fetching the client.
DELETE /api/v1/clients/{id}
Delete a client from the database.
Path parameters
id (str) — Client ID
Responses
200 OK
Deletion confirmation
404 Not Found
Client not found
500 Internal Server Error
Unexpected error occurred while deleting the client.
GET /api/v1/clients/{id}/attributes
Retrieve the current attribute key/value pairs for a specific client.
Path parameters
id (str) — Client ID
Responses
200 OK
{ "attribute_key": "value", ... }404 Not Found
Client not found
500 Internal Server Error
Unexpected error occurred while fetching attributes.
POST /api/v1/clients/add
Register a new client or update an existing client. Called by clients during startup and registration.
Request body
{ "client_id": "...", "name": "...", "combiner_preferred": "...", "package": "local|remote", "client_version": "x.y.z" }
Responses
200 OK
Returns assigned combiner details
400 Bad Request
Validation or missing field
406 Not Acceptable
Incompatible client version
500 Internal Server Error
Unexpected error occurred while modifying the client store.
GET /api/v1/clients/config
Retrieve the controller’s client configuration, used during client discovery.
Query parameters
checksum (str) — true or false to include model checksum in the response.
Responses
200 OK
{ "network_id": "...", "discover_host": "...", "discover_port": 8092, "checksum": "..." }500 Internal Server Error
Unexpected error occurred while fetching client config.
GET /api/v1/clients/count
Count the number of clients matching optional query filters.
Uses the same filter fields as the main GET /api/v1/clients endpoint.
Query parameters
name (str) — Filter by client name
combiner (str) — Filter by assigned combiner ID
combiner_preferred (str) — Filter by preferred combiner ID
ip (str) — Filter by client IP
status (str) — Filter by client status
updated_at (str) — Filter by timestamp
Responses
200 OK
Integer count
500 Internal Server Error
Unexpected error occurred while counting clients.
POST /api/v1/clients/count
Count clients using complex filters supplied in the JSON body. Allows multi-value (“in”) filtering using comma-separated values.
Request body
Any field from the client object may be included:
{ "name": "client1", "status": "active", "combiner": "combiner123" }
Responses
200 OK
Integer count
500 Internal Server Error
Unexpected error occurred while counting clients.
POST /api/v1/clients/list
Retrieve a list of clients using complex filters provided in the JSON body. Allows multi-value (“in”) filtering using comma-separated values.
Request body
Any field from the client object may be included:
{ "name": "client1", "status": "active", "combiner": "combiner123" }
Headers
X-Limit (int) — The maximum number of clients to retrieve
X-Skip (int) — The number of clients to skip
X-Sort-Key (str) — The key to sort the clients by
X-Sort-Order (str) — The order to sort the clients in (‘asc’ or ‘desc’)
Responses
200 OK
A list of clients.
{ "count": <int>, "result": [ { "client_id": "<string>", "name": "<string>", "ip": "<string>", "status": "<string>" }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching clients.
GET /api/v1/combiners
Retrieves a list of combiners based on the provided parameters. By specifying a parameter in the url, you can filter the combiners based on that parameter, and the response will contain only the combiners that match the filter.
Query parameters
name (str) — The name of the combiner
address (str) — The address of the combiner
ip (str) — The ip of the combiner
Headers
X-Limit (int) — The maximum number of combiners to retrieve
X-Skip (int) — The number of combiners to skip
X-Sort-Key (str) — The key to sort the combiners by
X-Sort-Order (str) — The order to sort the combiners in (‘asc’ or ‘desc’)
Responses
200 OK
A list of combiners and the total count.
{ "count": <int>, "result": [ { "name": "<string>", "combiner_id": "<string>", "address": "<string>", "ip": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching combiners.
PATCH /api/v1/combiners/{combiner_id}
Updates a combiner based on the provided data.
Path parameters
combiner_id (str) — Combiner ID
Request body
{ "internal_hostname": "...", "public_hostname": "..." }
Responses
200 OK
Combiner updated
400 Bad Request
Validation error
404 Not Found
Combiner not found
500 Internal Server Error
Unexpected error occurred while updating combiner.
GET /api/v1/combiners/{id}
Retrieve a single combiner by ID.
Path parameters
id (str) — Combiner ID
Responses
200 OK
Combiner object
404 Not Found
Combiner does not exist
500 Internal Server Error
Unexpected error occurred while fetching combiner.
DELETE /api/v1/combiners/{id}
Delete a combiner by ID.
Path parameters
id (str) — Combiner ID
Responses
200 OK
Deletion confirmation
404 Not Found
Combiner does not exist
500 Internal Server Error
Unexpected error occurred while deleting combiner.
POST /api/v1/combiners/clients/count
Get the number of clients connected to each of the specified combiners.
Request body
The combiners field is a comma-separated list of combiner IDs.
{ "combiners": "combiner1,combiner2,combiner3" }
Responses
200 OK
{ "result": [ {"combiner_id": "...", "client_count": <int>}, ... ] }500 Internal Server Error
Unexpected error occurred while requesting connected clients.
GET /api/v1/combiners/count
Count combiners matching optional query filters.
Query parameters
name (str) — Filter by combiner name
address (str) — Filter by address
ip (str) — Filter by IP address
Responses
200 OK
Integer count
500 Internal Server Error
Unexpected error occurred while counting combiners.
POST /api/v1/combiners/count
Count combiners using complex filters supplied in the request body.
Request body
{ "name": "combiner-1", "address": "tcp://...", "ip": "10.0.0.1" }
Responses
200 OK
Integer count
500 Internal Server Error
Unexpected error occurred while counting combiners.
POST /api/v1/combiners/list
Retrieve a list of combiners, filtered by complex POST body rules.
POST body allows passing filters directly without URL limits.
Values containing commas are treated as IN queries (e.g., “name”: “c1,c2”).
Request body
{ "name": "combiner-1", "address": "tcp://...", "ip": "10.0.0.1" }
Headers
X-Limit (int) — The maximum number of combiners to retrieve
X-Skip (int) — The number of combiners to skip
X-Sort-Key (str) — The key to sort the combiners by
X-Sort-Order (str) — The order to sort the combiners in (‘asc’ or ‘desc’)
Responses
200 OK
A list of combiners and the total count.
{ "count": <int>, "result": [ { "name": "<string>", "combiner_id": "<string>", "address": "<string>", "ip": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching combiners.
GET /api/v1/statuses
List status entries with optional filtering, pagination, and sorting.
A status is a log-like event emitted by components (controller, combiners, clients, etc.) and is typically used for monitoring, debugging, or tracking session progress.
Query parameters
type (str) — status/event type
sender.name (str) — name of the sender (e.g. combiner/client name)
sender.role (str) — role of the sender (e.g.
controller,combiner,client)session_id (str) — associated session ID
log_level (str) — log level (e.g.
INFO,WARNING,ERROR)correlation_id (str) — correlation ID that ties multiple events together
other_fields (str) — Any other fields supported by the status store
Headers
X-Limit (int) — max number of statuses to return
X-Skip (int) — number of statuses to skip
X-Sort-Key (str) — field name to sort by
X-Sort-Order (str) —
'asc'or'desc'
Responses
200 OK
A list of statuses.
{ "count": <int>, "result": [ { "id": "<string>", "type": "<string>", "session_id": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching statuses.
POST /api/v1/statuses
Submit a new status entry from a combiner or client.
Body example (client)
{
"sender": { "client_id": "abc-123" },
"type": "MODEL_UPDATE",
"log_level": "INFO",
"status": "..."
}
Body example (combiner)
{
"sender": { "combiner_id": "combiner-1" },
"type": "MODEL_UPDATE",
"log_level": "INFO",
"status": "..."
}
Responses
201 Created- Status received and persisted successfully.400 Bad Request-senderis missing, invalid, or the referenced client/combiner cannot be resolved.500 Internal Server Error- An unexpected error occurred while processing the request.
GET /api/v1/statuses/{id}
Retrieve a single status entry by its internal ID.
Path parameters
id (str) — internal status identifier
Responses
200 OK
full status object
404 Not Found
if no status exists with the given ID
500 Internal Server Error
Unexpected error occurred while fetching the status.
GET /api/v1/statuses/count
Count statuses matching the given query filters.
Query parameters
type (str) — status/event type
sender.name (str) — name of the sender
sender.role (str) — role of the sender
session_id (str) — associated session ID
log_level (str) — log level
correlation_id (str) — correlation ID
Responses
200 OK
integer count
500 Internal Server Error
Unexpected error occurred while counting statuses.
POST /api/v1/statuses/count
Count statuses using POST-body filters.
This endpoint mirrors GET /api/v1/statuses/count but accepts more complex
filters in the body. Comma-separated values are interpreted as "IN" filters.
Request body
client_id (str, optional) — string
model_id (str, optional) — string
correlation_id (str, optional) — string
{ "client_id": "<string>", "model_id": "<string>", "correlation_id": "<string>" }
Responses
200 OK
integer count
500 Internal Server Error
Unexpected error occurred while counting statuses.
GET /api/v1/statuses/histogram
Return time-bucketed event counts for matching statuses.
Useful for rendering a timeline histogram where the user can drag to select a time range of interest.
Query parameters
buckets (int, optional) — number of equal-width time buckets, default 50, max 200
start_date (str, optional) — ISO-8601 datetime, inclusive lower bound
end_date (str, optional) — ISO-8601 datetime, exclusive upper bound
type (str, optional) — filter by status type
sender.name (str, optional) — filter by sender name
sender.role (str, optional) — filter by sender role
log_level (str, optional) — filter by log level
Any other fields supported by the status store
Responses
200 OK
Array of time-bucket objects.
[ {"timestamp": "<ISO datetime>", "count": <int>}, ... ]500 Internal Server Error
Unexpected error occurred while building the histogram.
POST /api/v1/statuses/list
List statuses using POST-body filters for more complex queries.
Filters are provided in the request body
Comma-separated values are treated as
"IN"filters (i.e. match any of the values)
Request body
type (str, optional) — string
sender.name (str, optional) — string
sender.role (str, optional) — string
session_id (str, optional) — string
log_level (str, optional) — string
{ "type": "event,error", "sender.name": "combiner-1", "session_id": "session-123", "log_level": "WARNING,ERROR" }
Headers
X-Limit (int) — max number of statuses to return
X-Skip (int) — number of statuses to skip
X-Sort-Key (str) — field name to sort by
X-Sort-Order (str) —
'asc'or'desc'
Responses
200 OK
A list of statuses matching filters.
{ "count": <int>, "result": [ { "id": "<string>", "type": "<string>", "session_id": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching statuses.
Sessions, Rounds, and Runs
Endpoints that control training sessions, orchestration rounds, and execution runs.
GET /api/v1/rounds
List training rounds with optional filters, pagination, and sorting.
Use query parameters to filter rounds and headers to control pagination and sort order.
Query parameters
status (str) — status of the round (e.g.
pending,running,completed,failed)round_id (str) — round identifier
Headers
X-Limit (int) — maximum number of rounds to return
X-Skip (int) — number of rounds to skip (offset)
X-Sort-Key (str) — field to sort by (e.g.
round_id,status,updated_at)X-Sort-Order (str) —
'asc'or'desc'
Responses
200 OK
A list of rounds.
{ "count": <int>, "result": [ { "round_id": "<string>", "status": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching rounds.
GET /api/v1/rounds/{id}
Retrieve a single training round by its internal ID.
Path parameters
id (str) — round document identifier
Responses
200 OK
A round object.
{ ... Round ... }404 Not Found
no round with the given ID exists
500 Internal Server Error
Unexpected error occurred while fetching the round.
GET /api/v1/rounds/count
Count rounds matching optional query filters.
Query parameters
round_id (str) — round identifier
status (str) — round status
Responses
200 OK
Number of rounds.
<integer>
500 Internal Server Error
Unexpected error occurred while counting rounds.
POST /api/v1/rounds/count
Count rounds using POST-body filters.
Works like GET /api/v1/rounds/count but supports more complex filters in the
request body. Comma-separated values are treated as "IN" filters.
Request body
status (str, optional) — string
round_id (str, optional) — string
{ "status": "<string>", "round_id": "<string>" }
Responses
200 OK
Number of rounds.
<integer>
500 Internal Server Error
Unexpected error occurred while counting rounds.
POST /api/v1/rounds/list
List rounds using POST-body filters.
Works like GET /api/v1/rounds but supports more complex filters in the request
body. Comma-separated values are treated as "IN" filters.
Request body
status (str, optional) — string
round_id (str, optional) — string
{ "status": "<string>", "round_id": "<string>" }
Headers
X-Limit (int) — maximum number of rounds to return
X-Skip (int) — number of rounds to skip (offset)
X-Sort-Key (str) — field to sort by
X-Sort-Order (str) —
'asc'or'desc'
Responses
200 OK
A list of rounds.
{ "count": <int>, "result": [ { "round_id": "<string>", "status": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching rounds.
GET /api/v1/runs
Retrieve a list of training runs with optional filtering, pagination, and sorting.
A run represents a full top-level execution cycle (e.g., a complete training workflow), which may contain multiple sessions and rounds.
Query parameters
Any run metadata field (e.g.
session_id,status, etc.)
Headers
X-Limit (int) — max number of runs to return
X-Skip (int) — number of runs to skip
X-Sort-Key (str) — field to sort by
X-Sort-Order (str) —
'asc'or'desc'
Responses
200 OK
A list of runs.
{ "count": <int>, "result": [ { "run_id": "<string>", "session_id": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching runs.
GET /api/v1/runs/{id}
Retrieve a single run by its internal ID.
Path parameters
id (str) — run ID
Responses
200 OK
Run object.
{ "run_id": "<string>", "session_id": "<string>", ... }404 Not Found
no run exists with the provided ID
500 Internal Server Error
Unexpected error occurred while fetching the run.
GET /api/v1/runs/count
Count runs matching the provided query filters.
Query parameters
Any run field
Responses
200 OK
integer count
500 Internal Server Error
Unexpected error occurred while counting runs.
POST /api/v1/runs/count
Count runs using POST-body filters.
Supports comma-separated "IN" style filters.
Request body
status (str, optional) — string
{ "status": "pending,running" }
Responses
200 OK
integer count
500 Internal Server Error
Unexpected error occurred while counting runs.
POST /api/v1/runs/list
Retrieve runs using POST-body filters for more complex queries.
Comma-separated values in the body are treated as "IN" filters.
Request body
status (str, optional) — string
session_id (str, optional) — string
{ "status": "completed,failed", "session_id": "abc123" }
Headers
X-Limit (int) — limit
X-Skip (int) — skip
X-Sort-Key (str) — sort key
X-Sort-Order (str) — sort order
Responses
200 OK
A list of runs.
{ "count": <int>, "result": [ { "run_id": "<string>", "session_id": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching runs.
GET /api/v1/sessions
List sessions with optional filtering, pagination, and sorting.
A session represents a specific training configuration and lifecycle, typically containing multiple rounds and referencing a seed model.
Query parameters
status (str) — filter by session status (e.g.
pending,running,completed,failed)session_id (str) — filter by external session identifier
name (str) — filter by session name
seed_model_id (str) — filter by seed model identifier
Headers
X-Limit (int) — max number of sessions to return
X-Skip (int) — number of sessions to skip
X-Sort-Key (str) — field name to sort by
X-Sort-Order (str) —
'asc'or'desc'
Responses
200 OK
A list of session objects.
{ "count": <int>, "result": [ { "session_id": "<string>", "status": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching sessions.
POST /api/v1/sessions
Create a new session (configuration only, not started).
If session_config.helper_type is omitted, the active helper from the
current profile will be used.
Request body
name (str) — name
description (str) — description
session_config (dict) — config details
{ "name": "My training session", "description": "Experiment 1", "session_config": { "model_id": "seed-model-id", "rounds": 10, "clients_required": 3, "helper_type": "numpyhelper", "server_functions": "def aggregator(...): ..." } }server_functionsmust be a string and not exceedMAX_SERVER_FUNCTIONS_LEN.
Responses
201 Created
full created session object
400 Bad Request
validation / missing field / invalid object
500 Internal Server Error
Unexpected error occurred while creating the session.
GET /api/v1/sessions/{id}
Retrieve a single session by its internal ID.
Path parameters
id (str) — internal session identifier (database ID)
Responses
200 OK
full session object
404 Not Found
if no session exists with the given ID
500 Internal Server Error
Unexpected error occurred while fetching the session.
PATCH /api/v1/sessions/{id}
Partially update a session. Only the fields provided in the request body will be modified.
Path parameters
id (str) — internal session ID
Request body
JSON object containing fields to update.
session_idin the body is ignored (cannot change primary identifier).
Responses
200 OK
updated session object
400 Bad Request
validation or missing fields
404 Not Found
session does not exist
500 Internal Server Error
Unexpected error occurred while patching the session.
PUT /api/v1/sessions/{id}
Fully replace a session’s data with the payload provided.
Path parameters
id (str) — internal session ID
Request body
Full session representation.
session_idin the payload will be set toid.
Responses
200 OK
updated session object
400 Bad Request
validation or missing fields
404 Not Found
session does not exist
500 Internal Server Error
Unexpected error occurred while replacing the session.
GET /api/v1/sessions/count
Count sessions matching provided query filters.
Query parameters
session_id (str) — filter by external session identifier
status (str) — filter by session status
name (str) — filter by session name
seed_model_id (str) — filter by seed model identifier
Responses
200 OK
integer count
500 Internal Server Error
Unexpected error occurred while counting sessions.
POST /api/v1/sessions/count
Count sessions using POST-body filters.
Supports more complex filters than the GET variant. Comma-separated
values are treated as "IN" filters.
Request body
status (str, optional) — string
session_id (str, optional) — string
{ "status": "pending,running", "session_id": "session-123" }
Responses
200 OK
integer count
500 Internal Server Error
Unexpected error occurred while counting sessions.
POST /api/v1/sessions/list
List sessions using POST-body filters for more complex queries.
Comma-separated values in the body are treated as "IN" filters.
Request body
status (str, optional) — string
session_id (str, optional) — string
{ "status": "running,completed", "session_id": "session-123" }
Headers
X-Limit (int) — limit
X-Skip (int) — skip
X-Sort-Key (str) — sort key
X-Sort-Order (str) — sort order
Responses
200 OK
A list of session objects.
{ "count": <int>, "result": [ { "session_id": "<string>", "status": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching sessions.
POST /api/v1/sessions/start
Start a standard federated learning session.
This triggers the controller to start running rounds for an already-created session.
Request body
session_id (str) — ID of the session to start
rounds (int, optional) — number of rounds to run; defaults to
session_config.roundsround_timeout (int, optional) — per-round timeout in seconds
model_name_prefix (str, optional) — prefix for produced model names
client_ids (str, optional) — comma-separated list of specific client IDs to use
Behavior
Fails if
The controller is not in
idlestate.Not enough clients are available to satisfy
clients_required.The seed model for the session cannot be found.
Responses
200 OK
session successfully started
400 Bad Request
invalid input or session/controller precondition not met
500 Internal Server Error
failed to send command to controller or other unexpected error
Metrics, Telemetry, and Helpers
Endpoints for metrics, telemetry, and supporting helper operations.
GET /api/v1/helpers/active
Retrieve the currently active helper implementation.
The active helper controls how certain client-side operations (such as serialization or data handling) are performed in the network.
Responses
200 OK
Active helper name.
"<active_helper_name>"
Example:
"numpyhelper","binaryhelper","androidhelper"500 Internal Server Error
Unexpected error occurred while fetching the active helper.
PUT /api/v1/helpers/active
Set the active helper implementation for the network.
This updates the active profile so that subsequent operations use the specified helper type.
Request body
helper (str) — “numpyhelper” | “binaryhelper” | “androidhelper”
{
"helper": "numpyhelper"
}
Responses
200 OK
Active helper set.
{ "message": "Active helper set", "active_helper": "<helper_name>" }400 Bad Request
Invalid helper provided.
{"message": "Helper is required to be either 'numpyhelper', 'binaryhelper' or 'androidhelper'"}500 Internal Server Error
Unexpected error occurred while setting the active helper.
GET /api/v1/metrics
Retrieve a list of metrics with optional filtering, pagination, and sorting.
Query parameters
sender.name (str) —
sender.rolefiltermodel_id (str) —
model_stepfilterround_id (str) —
session_idfilter
Headers
X-Limit (int) —
X-SkipfilterX-Sort-Key (str) —
X-Sort-Orderfilter
Responses
200 OK
A list of metric objects.
{ "count": <int>, "result": [ { "id": "<string>", "sender": {"name": "<string>"}, "model_id": "<string>", "round_id": "<string>", }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching metrics.
GET /api/v1/metrics/{id}
Retrieve a single metric by ID.
Path parameters
id (str) — ID of the metric
Responses
200 OK
The metric object.
{ ... Metric object ... }404 Not Found
Metric not found
500 Internal Server Error
Unexpected error occurred while fetching the metric.
GET /api/v1/metrics/count
Count metrics matching optional query filters.
Supports the same filters as GET /api/v1/metrics.
Responses
200 OK
Total count of filtered metrics.
<integer>
500 Internal Server Error
Unexpected error occurred while counting metrics.
POST /api/v1/metrics/count
Count metrics using POST-body filters. Supports more complex filter syntax than the GET version.
Request body
sender.role (str, optional) — string
round_id (str, optional) — string
{ "sender.role": "client,combiner", "round_id": "123" }
Responses
200 OK
Total count of filtered metrics.
<integer>
500 Internal Server Error
Unexpected error occurred while counting metrics.
POST /api/v1/metrics/list
Retrieve a list of metrics using POST-body filters.
Supports all GET filters plus more complex queries using request body, e.g. multi-value comma-separated fields.
Headers
X-Limit (int) — limit
X-Skip (int) — skip
X-Sort-Key (str) — key
X-Sort-Order (str) — desc
Request body
<field> (str) — “<value or list>”
{
"<field>": "<value or list>"
}
Responses
200 OK
A list of metric objects.
{ "count": <int>, "result": [ { "id": "<string>", "sender": {"name": "<string>"}, "model_id": "<string>", "round_id": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching metrics.
GET /api/v1/telemetry
List telemetry records with optional filtering, pagination, and sorting.
Telemetry entries typically capture system- or client-level metrics and environment data that can be used for monitoring and analytics.
Query parameters
Any field supported by the telemetry store (for example
client_id,session_id,key, timestamps, etc., depending on your schema).
Headers
X-Limit (int) — The maximum number of telemetry items to retrieve
X-Skip (int) — The number of telemetry items to skip
X-Sort-Key (str) — The key to sort the telemetry items by
X-Sort-Order (str) — The order to sort the telemetry items in (‘asc’ or ‘desc’)
Responses
200 OK
A list of telemetry data.
{ "count": <int>, "result": [ { "client_id": "<string>", "session_id": "<string>", "key": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching telemetry.
POST /api/v1/telemetry
Create a new telemetry record.
Useful for components that want to push structured telemetry or environment data into the controller’s state store.
Request body
client_id (str) — string
key (str) — string
meta (dict) — additional context
Must match the fields expected by a Telemetry object.
Responses
201 Created
newly created telemetry as JSON
400 Bad Request
validation / missing field / value errors
500 Internal Server Error
Unexpected error occurred while creating the telemetry record.
GET /api/v1/telemetry/{id}
Retrieve a single telemetry record by its internal ID.
Path parameters
id (str) — internal telemetry identifier
Responses
200 OK
full telemetry object
404 Not Found
if no telemetry record exists with the given ID
500 Internal Server Error
Unexpected error occurred while fetching the telemetry record.
GET /api/v1/telemetry/count
Count telemetry records matching the given query filters.
Query parameters
Any field supported by the telemetry store (for example
client_id,session_id,key, timestamps, etc.)
Responses
200 OK
integer count
500 Internal Server Error
Unexpected error occurred while counting telemetry records.
POST /api/v1/telemetry/count
Count telemetry records using POST-body filters.
This endpoint mirrors GET /api/v1/telemetry/count but accepts filters in the
request body (JSON or form-encoded), which can be more convenient for
complex or large filter sets.
Request body
client_id (str, optional) — string
key (str, optional) — string
{ "client_id": "client-1,client-2", "key": "gpu_mem_usage" }
Responses
200 OK
integer count
500 Internal Server Error
Unexpected error occurred while counting telemetry records.
POST /api/v1/telemetry/list
List telemetry records using POST-body filters for more complex queries.
Filters are provided in the request body (JSON or form-encoded)
Comma-separated values are interpreted as
"IN"filters (match any of the values)
Request body
client_id (str, optional) — string
key (str, optional) — string
session_id (str, optional) — string
{ "client_id": "client-1,client-2", "key": "cpu_usage", "session_id": "session-123" }
Headers
X-Limit (int) — The maximum number of telemetry items to retrieve
X-Skip (int) — The number of telemetry items to skip
X-Sort-Key (str) — The key to sort the telemetry items by
X-Sort-Order (str) — The order to sort the telemetry items in (‘asc’ or ‘desc’)
Responses
200 OK
A list of telemetry data.
{ "count": <int>, "result": [ { "client_id": "<string>", "session_id": "<string>", "key": "<string>", ... }, ... ] }500 Internal Server Error
Unexpected error occurred while fetching telemetry.
Large File Uploads
Endpoints for uploading large files using chunked uploads.
POST /api/v1/file-upload/{upload_id}/abort
Abort and clean up an in-progress or completed upload.
Path parameters
upload_id (str) — the chunked upload ID
Responses
200 OK
Upload aborted.
{ "message": "Upload aborted" }404 Not Found
Unknown upload_id.
{ "message": "Unknown upload_id" }
POST /api/v1/file-upload/{upload_id}/chunk
Append a single chunk to the temp file.
Path parameters
upload_id (str) — the chunked upload ID
Headers
X-Chunk-Index (int) — zero-based chunk number
Content-Type —
application/octet-stream
Request body: raw binary chunk data.
Responses
200 OK
Chunk received.
{ "chunk_index": <int>, "bytes_received": <int> }400 Bad Request
Missing header or out-of-order chunk.
{ "message": "<error message>" }404 Not Found
Unknown upload_id.
{ "message": "Unknown upload_id" }
POST /api/v1/file-upload/{upload_id}/complete
Mark the upload as complete and return a file_token.
Path parameters
upload_id (str) — the chunked upload ID
Responses
200 OK
Upload complete.
{ "file_token": "<uuid>", "file_name": "<string>", "file_size": <int> }400 Bad Request
Not all chunks have been received.
{ "message": "<error message>" }404 Not Found
Unknown upload_id.
{ "message": "Unknown upload_id" }
POST /api/v1/file-upload/init
Initiate a chunked upload.
Request body
file_name (str) — original filename
file_size (int) — total file size in bytes (max 10 GB, server-side configurable)
chunk_size (int, optional) — requested chunk size in bytes (clamped to 256 KB – 10 MB, server-side configurable; defaults to 900 KB)
Responses
200 OK
Chunked upload created.
{ "upload_id": "<uuid>", "chunk_size": <int>, "total_chunks": <int> }400 Bad Request
Validation error (missing fields, file too large, too many chunks).
{ "message": "<error message>" }