.. # Copyright (c) 2026, Arm Limited. # # SPDX-License-Identifier: MIT ################## Scheduler REST API ################## The scheduler is a long-running service that manages access to SUT classes and dispatches queued work onto concrete SUT instances as they become available. It provides a REST API for: * creating scheduler users and API tokens * submitting plans for execution, tracking their progress, reprioritizing and cancelling them * acquiring and releasing manual leases on SUTs * querying SUT class metadata and usage The main use cases are: * **Plan execution**: submit a plan that targets a SUT class and let the scheduler split the plan and dispatch onto available SUTs in parallel. * **SUT leasing**: request a lease on a SUT from a SUT class, wait for a SUT to become available, and release it when finished. * **Operational reporting**: inspect leases, plans, and SUT class usage. .. note:: Users are expected to interact with the scheduler via the CLI commands (see :doc:`../user-guide/scheduler`). Those commands wrap the API documented here. The API is documented to enable integration with other systems. ************** Authentication ************** All endpoints require a bearer token in the ``Authorization`` header: .. code-block:: text Authorization: Bearer Tokens are created via ``POST /users``. ************ Capabilities ************ The scheduler enforces capabilities on each endpoint: * ``CAP_ADMIN``: unrestricted administrative access * ``CAP_EXEC``: submit and modify plans * ``CAP_LEASE``: acquire and release manual leases * ``CAP_QUERY``: query scheduler state An admin token bypasses ownership checks. Non-admin users are restricted to operating only on their own leases and plans. ************* Content Types ************* Most requests and all responses use JSON. Plan submission is the exception: ``POST /plans`` accepts either JSON or ``multipart/form-data``. Multipart must be used when the plan references local files that need to be uploaded alongside the plan payload (e.g. kernel images). ********* Endpoints ********* ----- Users ----- ``POST /users`` Create a new scheduler user. Requires ``CAP_ADMIN``. **Request body**:: { "name": "alice", "capabilities": "lease,query,exec" } **Response** ``201``:: { "status": "success", "user_id": 3, "token": "" } ----- Plans ----- ``POST /plans`` Submit a plan for scheduler execution. Requires ``CAP_EXEC``. The scheduler validates the plan, stores any uploaded input files under the plan storage directory, stores a normalized ``plan.yaml``, splits the plan into plan jobs, and queues those jobs for dispatch. If the scheduler was started with a configured resultstore, plans publish results there by default; this can be disabled per-submission with ``publish``. **JSON request body**:: { "plan": { ... plan object ... }, "priority": 5, "publish": true } **Multipart request**: * form field ``payload`` containing JSON with ``plan``, ``priority``, and optional ``publish`` * repeated file field ``files`` for any local files referenced by the plan **Response** ``201``:: { "status": "success", "plan_id": 11 } ``GET /plans`` List plans. Requires ``CAP_QUERY``. Optional query parameters to filter the response. If not provided, acts as if all values were provided: * ``states=queued,running,success,failed,cancelled`` * ``users=alice,bob`` The special user value ``__current__`` may be used to mean the authenticated user. ``GET /plans/`` Retrieve a single plan. Requires ``CAP_QUERY``. ``PATCH /plans/`` Modify a plan. Requires ``CAP_EXEC``. Non-admin users may only modify their own plans. Supported fields: * ``priority``: reprioritize all non-completed child jobs * ``cancel``: boolean; when ``true`` requests plan cancellation Either field may be provided on its own, or both together. **Request body**:: { "priority": 8, "cancel": false } **Response** ``200``:: { "status": "success" } Plan fields ``plan_id`` Plan id. ``user`` Object containing ``id`` and ``name``. ``sutclass`` Object containing ``id`` and ``name``. ``priority`` Plan priority. ``state`` Plan state. One of ``queued``, ``running``, ``success``, ``failed``, or ``cancelled``. ``total_jobs`` Number of split plan jobs. ``completed_jobs`` Number of split plan jobs that completed successfully. ``queued_at``, ``started_at``, ``completed_at`` plan timestamps. ------ Leases ------ ``POST /leases`` Queue a manual lease against a SUT class. Requires ``CAP_LEASE``. **Request body**:: { "sutclass": "myclass", "priority": 5 } **Response** ``201``:: { "status": "success", "lease_id": 7 } ``PATCH /leases/`` Release a lease. Requires ``CAP_LEASE``. Non-admin users may only release their own leases. **Response** ``200``:: { "status": "success" } ``GET /leases`` List leases. Requires ``CAP_QUERY``. Optional query parameters to filter the response. If not provided, acts as if all values were provided: * ``states=queued,acquired,released,failed,cancelled`` * ``users=alice,bob`` The special user value ``__current__`` may be used to mean the authenticated user. ``GET /leases/`` Retrieve a single lease. Requires ``CAP_QUERY``. Lease fields ``lease_id`` Lease id. ``user`` Object containing ``id`` and ``name``. ``job_id`` Backing job id. ``state`` Lease state. One of ``queued``, ``acquired``, ``released``, ``failed``, or ``cancelled``. ``priority`` Lease priority. ``sutclass`` Object containing ``id`` and ``name``. ``sut`` The acquired SUT description, or ``null`` if not yet acquired. ``queued_at``, ``started_at``, ``completed_at`` Timestamps for the backing job lifecycle. ----------- SUT Classes ----------- ``GET /sutclasses`` List SUT classes known to the scheduler. Requires ``CAP_QUERY``. Optional query parameters: * ``from=`` * ``to=`` When ``from`` and/or ``to`` are provided, the server calculates ``usage`` only within that time window. When neither is provided, ``usage`` is the scheduler's accumulated all-time usage counter. SUT class fields ``id`` SUT class id. ``name`` SUT class name. ``enabled`` Boolean indicating whether the SUT class is enabled. ``usage`` Runtime usage in seconds. ``created_at`` Timestamp when the SUT class row was created. ****** Errors ****** Errors return JSON of the form ``{"status": ""}``. The scheduler currently uses these status codes: * ``400`` ``invalid`` * ``400`` ``resourcebusy`` * ``401`` ``unauthorized`` * ``403`` ``forbidden`` * ``404`` ``notfound`` * ``409`` ``exists`` * ``413`` ``toobig`` * ``500`` ``internalerror`` ******** Examples ******** Create a scheduler user:: curl -X POST \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"alice","capabilities":"lease,query,exec"}' \ http://localhost:5000/users Acquire a lease:: curl -X POST \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"sutclass":"myclass","priority":5}' \ http://localhost:5000/leases Submit a plan using multipart upload:: curl -X POST \ -H "Authorization: Bearer $TOKEN" \ -F 'payload={"plan": {...}, "priority": 5}' \ -F 'files=@Image' \ http://localhost:5000/plans List SUT classes for a specific window:: curl -X GET \ -H "Authorization: Bearer $TOKEN" \ 'http://localhost:5000/sutclasses?from=2026-03-01T00:00:00+00:00&to=2026-04-01T00:00:00+00:00'