Bernstein Cluster API

The Cluster API from Bernstein — 18 operation(s) for cluster.

Operations 20

POST /cluster/nodes Register Node #
GET /cluster/nodes List Nodes #
POST /cluster/nodes/{node_id}/heartbeat Node Heartbeat #
DELETE /cluster/nodes/{node_id} Unregister Node #
POST /cluster/nodes/{node_id}/cordon Cordon Node #
POST /cluster/nodes/{node_id}/uncordon Uncordon Node #
POST /cluster/nodes/{node_id}/drain Drain Node #
GET /cluster/status Cluster Status #
POST /cluster/claims/gossip Gossip Claims #
POST /cluster/steal Steal Tasks #
POST /api/v1/cluster/nodes Register Node #
GET /api/v1/cluster/nodes List Nodes #
POST /api/v1/cluster/nodes/{node_id}/heartbeat Node Heartbeat #
DELETE /api/v1/cluster/nodes/{node_id} Unregister Node #
POST /api/v1/cluster/nodes/{node_id}/cordon Cordon Node #
POST /api/v1/cluster/nodes/{node_id}/uncordon Uncordon Node #
POST /api/v1/cluster/nodes/{node_id}/drain Drain Node #
GET /api/v1/cluster/status Cluster Status #
POST /api/v1/cluster/claims/gossip Gossip Claims #
POST /api/v1/cluster/steal Steal Tasks #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/bernstein-run:bernstein-run-cluster-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

bernstein-run-cluster-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Bernstein Task Server Cluster API
  description: 'Bernstein REST API - the open-source governance layer for AI agents, one git worktree per task.


    ## Authentication


    Authentication is ENABLED by default. Include a Bearer token in all requests:


    ```

    Authorization: Bearer

    ```


    To run without auth (development only), set `BERNSTEIN_AUTH_DISABLED=1` - this logs a loud warning and passes every request through.


    Public endpoints (no auth required): `/health`, `/health/ready`, `/health/live`, `/ready`, `/alive`, `/.well-known/agent.json`, `/docs`, `/openapi.json`, and the auth-flow endpoints (`/auth/login`, `/auth/oidc/callback`, etc.).


    Webhook and hook endpoints (`/webhook`, `/webhooks/*`, `/hooks/{session_id}`) authenticate via HMAC-SHA256 signatures - they do NOT accept Bearer tokens.


    ## Base URL


    Default: `http://127.0.0.1:8052`. Override with env vars `BERNSTEIN_HOST` and `BERNSTEIN_PORT`.


    ## Error Format


    All errors return JSON with a `detail` field:


    ```json

    {"detail": "Task not found: task-xyz"}

    ```


    | Status | Meaning |

    |--------|---------|

    | 400 | Bad request (validation error) |

    | 401 | Unauthorized (missing/invalid token) |

    | 403 | Forbidden (IP not in allowlist) |

    | 404 | Resource not found |

    | 409 | Conflict (task already in terminal state) |

    | 429 | Rate limited - respect the `Retry-After` header |

    | 500 | Internal server error |'
  version: 3.22.0
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0
  contact:
    name: Alex Chernysh
    url: https://github.com/sipyourdrink-ltd/bernstein
servers:
- url: http://{host}:{port}
  description: Task server started by the Bernstein CLI on the operator's own machine. There is no hosted instance; substitute the host and port of your install.
  variables:
    host:
      default: 127.0.0.1
      description: Interface the task server binds to. Loopback by default.
    port:
      default: '8052'
      description: Task server port. Override with BERNSTEIN_PORT.
tags:
- name: Cluster
paths:
  /cluster/nodes:
    post:
      summary: Register Node
      description: Register a node, or update the entry of one that is re-registering.
      operationId: register_node_cluster_nodes_post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NodeRegisterRequest'
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodeResponse'
        '401':
          description: Cluster authentication failed
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
    get:
      summary: List Nodes
      description: List all cluster nodes, optionally filtered by status.
      operationId: list_nodes_cluster_nodes_get
      parameters:
      - name: status
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Status
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/NodeResponse'
                title: Response List Nodes Cluster Nodes Get
        '400':
          description: Invalid node status
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /cluster/nodes/{node_id}/heartbeat:
    post:
      summary: Node Heartbeat
      description: Record a heartbeat from a cluster node.
      operationId: node_heartbeat_cluster_nodes__node_id__heartbeat_post
      parameters:
      - name: node_id
        in: path
        required: true
        schema:
          type: string
          title: Node Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NodeHeartbeatRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodeResponse'
        '401':
          description: Cluster authentication failed
        '404':
          description: Node not registered
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /cluster/nodes/{node_id}:
    delete:
      summary: Unregister Node
      description: Remove a node from the cluster.
      operationId: unregister_node_cluster_nodes__node_id__delete
      parameters:
      - name: node_id
        in: path
        required: true
        schema:
          type: string
          title: Node Id
      responses:
        '204':
          description: Successful Response
        '401':
          description: Cluster authentication failed
        '404':
          description: Node not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /cluster/nodes/{node_id}/cordon:
    post:
      summary: Cordon Node
      description: Cordon a node -- exclude from scheduling.
      operationId: cordon_node_cluster_nodes__node_id__cordon_post
      parameters:
      - name: node_id
        in: path
        required: true
        schema:
          type: string
          title: Node Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
                title: Response Cordon Node Cluster Nodes  Node Id  Cordon Post
        '401':
          description: Cluster authentication failed
        '404':
          description: Node not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /cluster/nodes/{node_id}/uncordon:
    post:
      summary: Uncordon Node
      description: Uncordon a node -- resume accepting tasks.
      operationId: uncordon_node_cluster_nodes__node_id__uncordon_post
      parameters:
      - name: node_id
        in: path
        required: true
        schema:
          type: string
          title: Node Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
                title: Response Uncordon Node Cluster Nodes  Node Id  Uncordon Post
        '401':
          description: Cluster authentication failed
        '404':
          description: Node not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /cluster/nodes/{node_id}/drain:
    post:
      summary: Drain Node
      description: Start draining a node -- cordon + signal agents to finish.
      operationId: drain_node_cluster_nodes__node_id__drain_post
      parameters:
      - name: node_id
        in: path
        required: true
        schema:
          type: string
          title: Node Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
                title: Response Drain Node Cluster Nodes  Node Id  Drain Post
        '401':
          description: Cluster authentication failed
        '404':
          description: Node not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /cluster/status:
    get:
      summary: Cluster Status
      description: Get cluster status summary.
      operationId: cluster_status_cluster_status_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClusterStatusResponse'
      tags:
      - Cluster
  /cluster/claims/gossip:
    post:
      summary: Gossip Claims
      description: 'Fold peer claim receipts into this node''s signed journal (#2558).


        The leaderless counterpart to ``POST /cluster/steal``: no node decides who

        gets what here. Each receipt is folded only after its Ed25519 signature and

        its chain link both verify, so an unverifiable receipt is never written.


        A receipt that does not extend the local head is *not* merged. It produces

        a signed ``fork`` receipt carrying the divergence entry index, which the

        response surfaces through ``forked``. Silent merge would be the one failure

        mode a leaderless design cannot recover from: two partitions would each

        hold a coherent-looking journal describing incompatible work.


        Authorisation reuses the node-heartbeat scope: gossip is a peer-to-peer

        fleet-membership operation, not an administrative one.'
      operationId: gossip_claims_cluster_claims_gossip_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClaimGossipRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClaimGossipResponse'
        '401':
          description: Cluster authentication failed
        '409':
          description: Node is not running the MESH topology
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /cluster/steal:
    post:
      summary: Steal Tasks
      description: 'Evaluate task stealing policy and reassign claimed tasks between nodes.


        Workers report their queue depths; the server runs the steal policy and

        returns a list of task reassignments. Stolen tasks are reset to ``open``

        so the receiver node can claim them.


        Authorisation requires the node-admin scope, like the other node-registry

        mutations (cordon, uncordon, drain, unregister) this sits beside in the

        operational-primitives table. It is deliberately NOT the heartbeat scope

        that ``POST /cluster/claims/gossip`` uses: gossip proves each receipt with

        its own Ed25519 signature and chain link inside the handler, so its bearer

        scope only has to establish fleet membership, whereas here the caller''s

        reported queue depths drive ``force_claim`` directly with no further proof

        to check.'
      operationId: steal_tasks_cluster_steal_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskStealRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskStealResponse'
        '401':
          description: Cluster authentication failed
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /api/v1/cluster/nodes:
    post:
      summary: Register Node
      description: Register a node, or update the entry of one that is re-registering.
      operationId: register_node_api_v1_cluster_nodes_post
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NodeRegisterRequest'
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodeResponse'
        '401':
          description: Cluster authentication failed
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
    get:
      summary: List Nodes
      description: List all cluster nodes, optionally filtered by status.
      operationId: list_nodes_api_v1_cluster_nodes_get
      parameters:
      - name: status
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          title: Status
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/NodeResponse'
                title: Response List Nodes Api V1 Cluster Nodes Get
        '400':
          description: Invalid node status
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /api/v1/cluster/nodes/{node_id}/heartbeat:
    post:
      summary: Node Heartbeat
      description: Record a heartbeat from a cluster node.
      operationId: node_heartbeat_api_v1_cluster_nodes__node_id__heartbeat_post
      parameters:
      - name: node_id
        in: path
        required: true
        schema:
          type: string
          title: Node Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NodeHeartbeatRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NodeResponse'
        '401':
          description: Cluster authentication failed
        '404':
          description: Node not registered
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /api/v1/cluster/nodes/{node_id}:
    delete:
      summary: Unregister Node
      description: Remove a node from the cluster.
      operationId: unregister_node_api_v1_cluster_nodes__node_id__delete
      parameters:
      - name: node_id
        in: path
        required: true
        schema:
          type: string
          title: Node Id
      responses:
        '204':
          description: Successful Response
        '401':
          description: Cluster authentication failed
        '404':
          description: Node not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /api/v1/cluster/nodes/{node_id}/cordon:
    post:
      summary: Cordon Node
      description: Cordon a node -- exclude from scheduling.
      operationId: cordon_node_api_v1_cluster_nodes__node_id__cordon_post
      parameters:
      - name: node_id
        in: path
        required: true
        schema:
          type: string
          title: Node Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
                title: Response Cordon Node Api V1 Cluster Nodes  Node Id  Cordon Post
        '401':
          description: Cluster authentication failed
        '404':
          description: Node not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /api/v1/cluster/nodes/{node_id}/uncordon:
    post:
      summary: Uncordon Node
      description: Uncordon a node -- resume accepting tasks.
      operationId: uncordon_node_api_v1_cluster_nodes__node_id__uncordon_post
      parameters:
      - name: node_id
        in: path
        required: true
        schema:
          type: string
          title: Node Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
                title: Response Uncordon Node Api V1 Cluster Nodes  Node Id  Uncordon Post
        '401':
          description: Cluster authentication failed
        '404':
          description: Node not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /api/v1/cluster/nodes/{node_id}/drain:
    post:
      summary: Drain Node
      description: Start draining a node -- cordon + signal agents to finish.
      operationId: drain_node_api_v1_cluster_nodes__node_id__drain_post
      parameters:
      - name: node_id
        in: path
        required: true
        schema:
          type: string
          title: Node Id
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
                title: Response Drain Node Api V1 Cluster Nodes  Node Id  Drain Post
        '401':
          description: Cluster authentication failed
        '404':
          description: Node not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /api/v1/cluster/status:
    get:
      summary: Cluster Status
      description: Get cluster status summary.
      operationId: cluster_status_api_v1_cluster_status_get
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClusterStatusResponse'
      tags:
      - Cluster
  /api/v1/cluster/claims/gossip:
    post:
      summary: Gossip Claims
      description: 'Fold peer claim receipts into this node''s signed journal (#2558).


        The leaderless counterpart to ``POST /cluster/steal``: no node decides who

        gets what here. Each receipt is folded only after its Ed25519 signature and

        its chain link both verify, so an unverifiable receipt is never written.


        A receipt that does not extend the local head is *not* merged. It produces

        a signed ``fork`` receipt carrying the divergence entry index, which the

        response surfaces through ``forked``. Silent merge would be the one failure

        mode a leaderless design cannot recover from: two partitions would each

        hold a coherent-looking journal describing incompatible work.


        Authorisation reuses the node-heartbeat scope: gossip is a peer-to-peer

        fleet-membership operation, not an administrative one.'
      operationId: gossip_claims_api_v1_cluster_claims_gossip_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClaimGossipRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ClaimGossipResponse'
        '401':
          description: Cluster authentication failed
        '409':
          description: Node is not running the MESH topology
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
  /api/v1/cluster/steal:
    post:
      summary: Steal Tasks
      description: 'Evaluate task stealing policy and reassign claimed tasks between nodes.


        Workers report their queue depths; the server runs the steal policy and

        returns a list of task reassignments. Stolen tasks are reset to ``open``

        so the receiver node can claim them.


        Authorisation requires the node-admin scope, like the other node-registry

        mutations (cordon, uncordon, drain, unregister) this sits beside in the

        operational-primitives table. It is deliberately NOT the heartbeat scope

        that ``POST /cluster/claims/gossip`` uses: gossip proves each receipt with

        its own Ed25519 signature and chain link inside the handler, so its bearer

        scope only has to establish fleet membership, whereas here the caller''s

        reported queue depths drive ``force_claim`` directly with no further proof

        to check.'
      operationId: steal_tasks_api_v1_cluster_steal_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskStealRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskStealResponse'
        '401':
          description: Cluster authentication failed
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      tags:
      - Cluster
components:
  schemas:
    TaskStealResponse:
      properties:
        actions:
          items:
            $ref: '#/components/schemas/TaskStealAction'
          type: array
          title: Actions
        total_stolen:
          type: integer
          title: Total Stolen
      type: object
      required:
      - actions
      - total_stolen
      title: TaskStealResponse
      description: Response for POST /cluster/steal.
    NodeCapacitySchema:
      properties:
        max_agents:
          type: integer
          title: Max Agents
          default: 6
        available_slots:
          type: integer
          title: Available Slots
          default: 6
        active_agents:
          type: integer
          title: Active Agents
          default: 0
        gpu_available:
          type: boolean
          title: Gpu Available
          default: false
        supported_models:
          items:
            type: string
          type: array
          title: Supported Models
      type: object
      title: NodeCapacitySchema
      description: Advertised capacity of a cluster node.
    ClaimGossipResponse:
      properties:
        head:
          type: string
          title: Head
        accepted:
          type: integer
          title: Accepted
        results:
          items:
            $ref: '#/components/schemas/ClaimGossipResult'
          type: array
          title: Results
        forked:
          type: boolean
          title: Forked
          default: false
      type: object
      required:
      - head
      - accepted
      - results
      title: ClaimGossipResponse
      description: 'Response for POST /cluster/claims/gossip.


        ``forked`` is surfaced at the top level because a fork is the one outcome

        that must not be lost in a per-receipt list an integrator might ignore.'
    NodeHeartbeatRequest:
      properties:
        capacity:
          anyOf:
          - $ref: '#/components/schemas/NodeCapacitySchema'
          - type: 'null'
      type: object
      title: NodeHeartbeatRequest
      description: Body for POST /cluster/nodes/{node_id}/heartbeat.
    TaskStealAction:
      properties:
        donor_node_id:
          type: string
          title: Donor Node Id
        receiver_node_id:
          type: string
          title: Receiver Node Id
        task_ids:
          items:
            type: string
          type: array
          title: Task Ids
      type: object
      required:
      - donor_node_id
      - receiver_node_id
      - task_ids
      title: TaskStealAction
      description: 'A single steal action: move tasks from donor to receiver.'
    ClaimGossipResult:
      properties:
        entry_hash:
          type: string
          title: Entry Hash
        status:
          type: string
          title: Status
        reason:
          anyOf:
          - type: string
          - type: 'null'
          title: Reason
        divergence_index:
          anyOf:
          - type: integer
          - type: 'null'
          title: Divergence Index
      type: object
      required:
      - entry_hash
      - status
      title: ClaimGossipResult
      description: Per-receipt outcome of a gossip push.
    ClaimGossipRequest:
      properties:
        receipts:
          items:
            additionalProperties: true
            type: object
          type: array
          title: Receipts
        head:
          anyOf:
          - type: string
          - type: 'null'
          title: Head
        node_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Node Id
      type: object
      required:
      - receipts
      title: ClaimGossipRequest
      description: 'Body for POST /cluster/claims/gossip - push signed claim receipts to a peer.


        ``receipts`` are the raw :class:`ClaimReceipt` wire dicts in journal order.

        ``head`` is the sender''s journal head, echoed back so the sender can tell

        convergence from divergence without a second round trip.'
    ClusterStatusResponse:
      properties:
        topology:
          type: string
          title: Topology
        total_nodes:
          type: integer
          title: Total Nodes
        online_nodes:
          type: integer
          title: Online Nodes
        offline_nodes:
          type: integer
          title: Offline Nodes
        total_capacity:
          type: integer
          title: Total Capacity
        available_slots:
          type: integer
          title: Available Slots
        active_agents:
          type: integer
          title: Active Agents
        nodes:
          items:
            $ref: '#/components/schemas/NodeResponse'
          type: array
          title: Nodes
      type: object
      required:
      - topology
      - total_nodes
      - online_nodes
      - offline_nodes
      - total_capacity
      - available_slots
      - active_agents
      - nodes
      title: ClusterStatusResponse
      description: Response for GET /cluster/status.
    NodeRegisterRequest:
      properties:
        name:
          type: string
          title: Name
          default: ''
        url:
          type: string
          title: Url
          default: ''
        capacity:
          $ref: '#/components/schemas/NodeCapacitySchema'
        labels:
          additionalProperties:
            type: string
          type: object
          title: Labels
        cell_ids:
          items:
            type: string
          type: array
          title: Cell Ids
      type: object
      title: NodeRegisterRequest
      description: Body for POST /cluster/nodes.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    NodeResponse:
      properties:
        id:
          type: string
          title: Id
        name:
          type: string
          title: Name
        url:
          type: string
          title: Url
        status:
          type: string
          title: Status
        capacity:
          $ref: '#/components/schemas/NodeCapacitySchema'
        last_heartbeat:
          type: number
          title: Last Heartbeat
        registered_at:
          type: number
          title: Registered At
        labels:
          additionalProperties:
            type: string
          type: object
          title: Labels
        cell_ids:
          items:
            type: string
          type: array
          title: Cell Ids
      type: object
      required:
      - id
      - name
      - url
      - status
      - capacity
      - last_heartbeat
      - registered_at
      - labels
      - cell_ids
      title: NodeResponse
      description: Serialised node in API responses.
    TaskStealRequest:
      properties:
        queue_depths:
          additionalProperties:
            type: integer
          type: object
          title: Queue Depths
      type: object
      title: TaskStealRequest
      description: Body for POST /cluster/steal - report queue depths and request rebalancing.