/v1/runsList runs#
Recent runs
The most recent runs, newest first, with their state computed from their logs.
Query parameters
limitinteger
How many runs: 20 by default, 200 at most.
Responses
200Runs, newest first.application/json
runsrequiredarray of RunSummary
Runs, newest first.
RunSummary · 12 fields
runrequiredstring
Run.
procedurerequiredstring
Procedure.
stepstring
Step running or last run.
suspendedrequiredboolean
Whether it is suspended.
pendingone of Pending | null
finishedboolean
Outcome, once finished.
reasonstring
Why it failed.
environmentrequiredstring
Environment.
targetsrequiredmap of string
Target of each role.
bystring
Who launched it.
started_at string · date-time
Start.
updated_at string · date-time
Last event.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/runs"import requests
BASE_URL = "http://localhost:8080"
response = requests.get(f"{BASE_URL}/v1/runs")
response.raise_for_status()
print(response.json())let base_url = "http://localhost:8080";
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/runs"))
.send()
.await?
.error_for_status()?;
let body: serde_json::Value = response.json().await?;
println!("{body:#}");Response
{
"runs": [
{
"run": "string",
"procedure": "string",
"step": "string",
"suspended": true,
"pending": null,
"finished": true,
"reason": "string",
"environment": "string",
"targets": {
"key": "string"
},
"by": "string",
"started_at": "2026-09-29T08:30:00Z",
"updated_at": "2026-09-29T08:30:00Z"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/runsLaunch run#
Launch a run
Resolves the run request against the current configuration into a self-contained resolved run, stores it in stellar_ir and submits it to the executor. The environment applies its policies: allowed procedures, draft packages, identity, hazardous telecommands only from a schedule where planning is mandatory. A run bound to a pass (plan) must start within it and fit before its LOS minus scheduler.margin; a manual run in in_orbit needs an available link.
Request body application/jsonrequired
runrequiredstring
Procedure.
librarystring
Library of the procedure, when several have a procedure of that name.
environmentrequiredstring
Environment.
targetsrequiredmap of string
Target of each role.
inputsmap of InputArg
Input values.
planstring
Pass the run is planned on, set by the scheduler.
faultsarray of FaultRequest
Faults of the simulations to switch on during the run: simulated targets only.
FaultRequest · 4 fields
targetrequiredstring
Role of the target, as in targets.
faultrequiredstring
Fault, as the simulation of the target names it.
atWhen it is switched on: after the start of the run, or of the first entry in a step.
Trigger · 2 fields
stepstring
Step whose first entry starts the delay: its name (Plateau), or its path (TVAC cycle / Plateau).
afterstring
Delay.
offone of Trigger | null
Responses
202Submitted: follow it on GET /v1/runs/{id}/events. warnings names the passes in progress it may outlast.application/json
runrequiredstring
Identifier of the run.
irrequiredstring
Hash of the resolved run in stellar_ir.
warningsarray of string
What the operator should know: a run that may end after the LOS of the pass in progress.
400Invalid body: api::invalid-body.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
401Identity required by the environment: api::anonymous, auth::jwt-required, auth::invalid-token.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
409Refused by the passes: run::pass-cancelled, run::not-booked, run::before-aos, run::window, run::receive-only, run::no-link.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
422The request does not resolve, or breaks a policy: run::not-allowed, run::draft-not-allowed, run::plan-required, run::must-be-scheduled, run::unknown-pass, run::link-component…application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl -X POST "http://localhost:8080/v1/runs" \
-H "Content-Type: application/json" \
-d '{
"run": "string",
"library": "string",
"environment": "string",
"targets": {
"key": "string"
},
"inputs": {
"key": true
},
"plan": "string",
"faults": [
{
"target": "string",
"fault": "string",
"at": {
"step": "string",
"after": "string"
},
"off": {
"step": "string",
"after": "string"
}
}
]
}'import requests
BASE_URL = "http://localhost:8080"
response = requests.post(
f"{BASE_URL}/v1/runs",
json={
"run": "string",
"library": "string",
"environment": "string",
"targets": {
"key": "string",
},
"inputs": {
"key": True,
},
"plan": "string",
"faults": [
{
"target": "string",
"fault": "string",
"at": {
"step": "string",
"after": "string",
},
"off": {
"step": "string",
"after": "string",
},
},
],
},
)
response.raise_for_status()
print(response.json())let base_url = "http://localhost:8080";
let response = reqwest::Client::new()
.post(format!("{base_url}/v1/runs"))
.json(&serde_json::json!({
"run": "string",
"library": "string",
"environment": "string",
"targets": {
"key": "string"
},
"inputs": {
"key": true
},
"plan": "string",
"faults": [
{
"target": "string",
"fault": "string",
"at": {
"step": "string",
"after": "string"
},
"off": {
"step": "string",
"after": "string"
}
}
]
}))
.send()
.await?
.error_for_status()?;
let body: serde_json::Value = response.json().await?;
println!("{body:#}");Response
{
"run": "string",
"ir": "string",
"warnings": [
"string"
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/runs/{id}Run status#
State of a run
Computed from its log: step running, suspended, question or decision waiting (with the role awaited for a hazardous confirmation), outcome.
Path parameters
idrequiredstring
Run identifier (ULID).
Responses
200State of the run.application/json
runrequiredstring
Run.
procedurerequiredstring
Procedure.
stepstring
Step running or last run.
suspendedrequiredboolean
Whether it is suspended.
pendingone of Pending | null
finishedboolean
Outcome, once finished.
reasonstring
Why it failed.
404Invalid identifier or no such run: run::unknown.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/runs/<id>"import requests
BASE_URL = "http://localhost:8080"
id = "<id>" # Run identifier (ULID).
response = requests.get(f"{BASE_URL}/v1/runs/{id}")
response.raise_for_status()
print(response.json())let base_url = "http://localhost:8080";
let id = "<id>"; // Run identifier (ULID).
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/runs/{id}"))
.send()
.await?
.error_for_status()?;
let body: serde_json::Value = response.json().await?;
println!("{body:#}");Response
{
"run": "string",
"procedure": "string",
"step": "string",
"suspended": true,
"pending": {
"path": "string",
"kind": "string",
"prompt": "string",
"role": "string"
},
"finished": true,
"reason": "string"
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/runs/{id}/eventsFollow run#
Follow a run (WebSocket)
Replays the log of the run, then follows it until its finished event. Each message is a RunEvent.
Path parameters
idrequiredstring
Run identifier (ULID).
Responses
101WebSocket: one RunEvent per message.application/json
atrequiredstring
Time of the event.
runrequiredstring
Run.
seqrequiredinteger · uint64
Position in the log, from 1.
404Invalid identifier.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/runs/<id>/events"import requests
BASE_URL = "http://localhost:8080"
id = "<id>" # Run identifier (ULID).
response = requests.get(f"{BASE_URL}/v1/runs/{id}/events")
response.raise_for_status()let base_url = "http://localhost:8080";
let id = "<id>"; // Run identifier (ULID).
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/runs/{id}/events"))
.send()
.await?
.error_for_status()?;Response
{
"by": "string",
"environment": "string",
"event": "started",
"inputs": {},
"ir": "string",
"library": "string",
"procedure": "string",
"targets": {
"key": "string"
}
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/runs/{id}/answersAnswer run#
Answer a question or a decision
Answers the ask of a step (a confirmation, or a typed value) or a decision (replay, skip, fail or abort in value), as the operator identified by the request. The executor checks the answer: role expected, a person who has not confirmed the step yet, token checked again with identity: jwt; a refused answer is logged as answer_refused.
Path parameters
idrequiredstring
Run identifier (ULID).
Request body application/jsonrequired
pathrequiredstring
Step asking, as in its asked or decision_required event.
acceptedrequiredboolean
Whether the operator confirms.
valueany
Typed answer, or decision: replay, skip, fail or abort.
Responses
400Invalid body, or no identity: api::invalid-body, api::anonymous.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
401Identity refused by the environment of the run.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
404Invalid identifier or no such run.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl -X POST "http://localhost:8080/v1/runs/<id>/answers" \
-H "Content-Type: application/json" \
-d '{
"path": "string",
"accepted": true,
"value": null
}' \
-o response.binimport requests
BASE_URL = "http://localhost:8080"
id = "<id>" # Run identifier (ULID).
response = requests.post(
f"{BASE_URL}/v1/runs/{id}/answers",
json={
"path": "string",
"accepted": True,
"value": None,
},
)
response.raise_for_status()
data = response.contentlet base_url = "http://localhost:8080";
let id = "<id>"; // Run identifier (ULID).
let response = reqwest::Client::new()
.post(format!("{base_url}/v1/runs/{id}/answers"))
.json(&serde_json::json!({
"path": "string",
"accepted": true,
"value": null
}))
.send()
.await?
.error_for_status()?;
let bytes = response.bytes().await?;Response
{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/runs/{id}/{action}Control run#
Suspend, resume or abort a run
suspend takes effect at the end of the current instruction and releases the leases of the run; resume takes them back, checks the targets again and applies the choice of the operator (replay the step where the run stopped, skip it, or abort); abort ends the run for good, without its if failed blocks. The command goes to the executor holding the run.
Path parameters
idrequiredstring
Run identifier (ULID).
actionrequiredstring
suspend, resume or abort.
Request body application/json
For resume only: the choice of the operator.
one of Resume | null
Responses
400Invalid body, or no identity.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
404Invalid identifier, or unknown command: api::unknown-command.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
409The run is not running (run::not-running) or the executor refused the command (run::refused).application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
504The executor did not answer: run::timeout.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl -X POST "http://localhost:8080/v1/runs/<id>/<action>" \
-H "Content-Type: application/json" \
-d '{
"choice": "string"
}' \
-o response.binimport requests
BASE_URL = "http://localhost:8080"
id = "<id>" # Run identifier (ULID).
action = "<action>" # `suspend`, `resume` or `abort`.
response = requests.post(
f"{BASE_URL}/v1/runs/{id}/{action}",
json={
"choice": "string",
},
)
response.raise_for_status()
data = response.contentlet base_url = "http://localhost:8080";
let id = "<id>"; // Run identifier (ULID).
let action = "<action>"; // `suspend`, `resume` or `abort`.
let response = reqwest::Client::new()
.post(format!("{base_url}/v1/runs/{id}/{action}"))
.json(&serde_json::json!({
"choice": "string"
}))
.send()
.await?
.error_for_status()?;
let bytes = response.bytes().await?;Response
{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}/v1/runs/{id}/reportRun report#
Test report of a run
The HTML report archived at the end of the run (stellar_reports), else rendered from its log so far. The same log always gives the same report.
Path parameters
idrequiredstring
Run identifier (ULID).
Responses
200The report.text/html
string
404Invalid identifier or no such run.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
503The MCS bus (NATS) is unavailable: api::unavailable.application/json
errorsrequiredarray of ErrorItem
Every error found.
ErrorItem · 3 fields
coderequiredstring
Stable code.
messagerequiredstring
Message for the operator.
helpstring
Suggested fix.
Request
curl "http://localhost:8080/v1/runs/<id>/report" \
-o response.binimport requests
BASE_URL = "http://localhost:8080"
id = "<id>" # Run identifier (ULID).
response = requests.get(f"{BASE_URL}/v1/runs/{id}/report")
response.raise_for_status()
data = response.contentlet base_url = "http://localhost:8080";
let id = "<id>"; // Run identifier (ULID).
let response = reqwest::Client::new()
.get(format!("{base_url}/v1/runs/{id}/report"))
.send()
.await?
.error_for_status()?;
let bytes = response.bytes().await?;Response
{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}{
"errors": [
{
"code": "string",
"message": "string",
"help": "string"
}
]
}