Base URL is the server started by:
csauto serve <runs_dir>serve starts the primary FastAPI server.
Example base URL:
http://127.0.0.1:8000
Interactive API documentation is available at:
http://127.0.0.1:8000/docs(Swagger UI)http://127.0.0.1:8000/redoc(ReDoc)
Authentication is optional.
If [api].token is configured in csauto.toml, each /api/* request must send either:
X-CSAUTO-TOKEN: <token>Authorization: Bearer <token>
Without a valid token, the server returns 401 Unauthorized.
Case list query format:
- many endpoints require
casequery parameter - accepted forms:
- repeated query:
?case=case0001&case=case0002 - comma-separated:
?case=case0001,case0002
- repeated query:
Boolean query values:
- true values:
1,true,yes - any other value is treated as false
Case validation:
- case IDs are validated and path traversal is blocked
- invalid case values return
400
Purpose:
- refresh and return all case rows + detected DOE columns
Query parameters:
log(optional, boolean): if true, logsrefreshactions in case history
Response:
{
"rows": [
{
"case_id": "case0001",
"status": "RUNNING",
"convergence": "",
"note": "",
"nprocs": 4,
"nt": 2,
"last_iter": 178,
"duration_s": 522,
"duration": "8m42s",
"last_mod": "2026-03-09T10:02:11",
"resu_size_mb": 128.4,
"doe": {
"density_value": "1.1"
}
}
],
"doe_columns": ["density_value", "turbulence_model", "ref_v"]
}Purpose:
- collect performance records from selected cases
Query parameters:
case(required)
Response:
{ "records": [...] }
Purpose:
- return residual rows as JSON
Query parameters:
case(required)limit(optional int, default0= no limit)include_history(optional boolean): include all RESU runs
Response:
{ "header": [...], "records": [...] }
Purpose:
- infer restart base iteration/time from latest run logs
Query parameters:
case(required)
Response:
{ "origins": { "case0001": { "iteration": 500, "time": 12.5 } } }
Purpose:
- scan log files for anomalies (error/warn/info)
Query parameters:
case(required)files(optional comma list): defaults to internal anomaly filesmax_hits(optional int, default200, clamped1..500)context(optional int, default6, clamped0..50): lines before and after hitsev(optional):all,error,warn,info, or comma mixq(optional): plain text filter
Response:
{ "items": [...] }
Each item contains:
case_id,file,severityline_html(highlighted + context)tail_index,tail_total
Purpose:
- list available residual columns for selected cases
Query parameters:
case(required)
Response:
{ "columns": ["iteration", "velocity", "pressure", ...] }
Purpose:
- render residuals plot as SVG
Query parameters:
case(required)columns(optional comma/space list)width(optional int, default900)height(optional int, default500)x_min(optional float, default0)include_history(optional boolean)
Response content-type:
image/svg+xml
Purpose:
- return tail content of a case file
Query parameters:
case(required)file(optional, defaultlisting)n(optional int, default200)
Response content-type:
text/plain
Purpose:
- list files in latest RESU run
Query parameters:
case(required)limit(optional int, default2000)
Response:
{ "files": [...] }
Purpose:
- list RESU run directories sorted by recency
Query parameters:
case(required)
Response:
{ "dirs": ["20260308-1413", "20260308-1347", ...] }
Purpose:
- list available probe/profile files for one case
Query parameters:
case(required)scope(optional):monitoring(default) orprofileslimit(optional int, default200)
Response:
{ "files": [...] }
Purpose:
- return probe CSV records
Query parameters:
case(required)probe(required)limit(optional int, default200)
Response:
{ "header": [...], "records": [...] }
Purpose:
- infer probe coordinates from associated coords file when available
Query parameters:
case(required)probe(required)column(optional)
Response:
{ "found": false }- or
{ "found": true, "x": 0.05, "y": 0.05, "z": 0.0, "source": "..." }
Purpose:
- list columns available in one or more probe files
Query parameters:
case(required)probeorprobes(required, comma or repeated)
Response:
{ "columns": [...] }
Purpose:
- render probe/profile plot as SVG
Query parameters:
case(required)probeorprobes(required)axis(optional, defaulttime)columns(optional comma/space list)width(optional int, default900)height(optional int, default500)include_history(optional boolean)x_min(optional float)time_min(legacy alias ifx_minabsent)
Response content-type:
image/svg+xml
Purpose:
- return a readable case file
Query parameters:
case(required)kind(required): examplesetup.xml,doe_row.csv,listing, ...
Response content-type:
text/plain
Purpose:
- compare a selected file across multiple cases against one base case
Query parameters:
case(required)base(optional, default first selected case)kind(optional, defaultsetup.xml)filter(optional regex)
Response content-type:
text/plaindiff output
Purpose:
- diff a file between exactly two cases
Query parameters:
case1(required)case2(required)kind(required)
Response content-type:
text/plain
Purpose:
- read per-case action history
Query parameters:
case(required)limit(optional int, default100, clamped1..1000)include_refresh(optional boolean, default false)actions(optional comma list to include)q(optional text filter)
Response:
{ "items": [...] }
Purpose:
- return highlighted HTML for XML content
Payload:
{ "content": "<xml>...</xml>" }Response content-type:
text/html
Purpose:
- return highlighted HTML for unified diff content
Payload:
{ "content": "@@ ..." }Response content-type:
text/html
Purpose:
- update an editable case file
Payload:
{
"case": "case0001",
"kind": "setup.xml",
"content": "<xml>...</xml>"
}Response:
{ "status": "ok" }Purpose:
- set/update a user note for a case
Payload:
{ "case": "case0001", "note": "investigate pressure drift" }Response:
{ "status": "ok" }Purpose:
- set convergence label for a finished case
Payload:
{ "case": "case0001", "convergence": "converged" }Allowed convergence values:
convergednot_converged- empty string (clear)
Constraint:
- case status must be
DONEorFAILED
Response:
{ "status": "ok" }Purpose:
- apply cleanup policies on selected case list
Payload example:
{
"cases": ["case0001", "case0002"],
"prune_resu": true,
"keep_last": 1,
"max_log_mb": 50,
"clear_cid": true,
"clear_pyc": false,
"dry_run": false,
"keep_resu": ["20260308-1413"],
"delete_resu": []
}Rules:
casesis requiredkeep_resuanddelete_resuare mutually exclusive
Response:
{
"resu_removed": 3,
"logs_truncated": 2,
"bytes_freed": 10485760,
"cid_removed": 1,
"pycache_removed": 0
}Purpose:
- kill one or multiple selected cases
Payload:
{ "cases": ["case0001", "case0002"] }Behavior:
- multi-case kill runs in parallel
- returns
500if any selected case fails to stop
Success response:
{ "status": "ok" }Purpose:
- launch code_saturne GUI for one case on server side
Payload:
{ "case": "case0001" }Notes:
- requires server
DISPLAY - runtime resolution errors are returned as
500
Success response:
{ "status": "ok" }Purpose:
- launch selected cases from web/API, with optional restart settings
Minimal payload:
{
"cases": ["case0001"],
"n": 4,
"nt": 2,
"max_parallel": 2
}Restart payload:
{
"cases": ["case0001"],
"n": 4,
"nt": 2,
"restart": true,
"restart_mode": "iterations",
"restart_value": 100,
"restart_path": "20260308-1413"
}Rules:
cases,n,ntare requiredn,nt,max_parallelmust be integers> 0restart_modeaccepted values:iterations,physical_timerestart_valuemust match selected mode constraints
Success response:
{ "status": "ok" }Common status codes:
200: success400: missing/invalid parameters401: unauthorized (token)404: resource not found500: internal/runtime/launch errors
Common error messages:
Missing case parameterMissing cases parameterMissing case, probe parametersMissing case, kind, content parametersn, nt, and max_parallel must be integers > 0restart_mode must be iterations or physical_time
Read status:
curl -s "http://127.0.0.1:8000/api/status"Read status with token:
curl -s -H "X-CSAUTO-TOKEN: my-token" \
"http://127.0.0.1:8000/api/status"Fetch residual SVG:
curl -s "http://127.0.0.1:8000/api/residuals_svg?case=case0001&columns=velocity,pressure" > residuals.svgRun a case from API:
curl -s -X POST "http://127.0.0.1:8000/api/run_case" \
-H "Content-Type: application/json" \
-d '{"cases":["case0001"],"n":4,"nt":2,"max_parallel":1}'