APIs
Studio recipes
These assume SIRIUS=http://localhost:8080 and a $TOK bearer on a secured deployment. Add -H "Authorization: Bearer $TOK" to each call. Concepts live on the Studio API page.
Create, file, sample, run
WS=$(curl -s -X POST "$SIRIUS/studio/workspaces" \
-H 'content-type: application/json' \
-d '{
"tenant_id":"default",
"name":"Normalize order",
"runtime_pack":"javascript",
"tags":["orders"]
}' | jq -r .id)
curl -s -X PUT "$SIRIUS/studio/workspaces/$WS/files" \
-H 'content-type: application/json' -d '{
"tenant_id":"default",
"path":"main.js",
"entrypoint":true,
"content":"const body = sirius.json.decode(msg.raw);\nbody.site = sirius.table.lookup(\"sites\", body.site_id, \"UNKNOWN\");\nresult = { message: body };"
}'
curl -s -X POST "$SIRIUS/studio/workspaces/$WS/samples/import" \
-H 'content-type: application/json' -d '{
"tenant_id":"default",
"name":"order-001",
"content":"{\"id\":\"A-1\",\"site_id\":\"west\"}",
"make_active":true
}'
curl -s -X POST "$SIRIUS/studio/workspaces/$WS/run" \
-H 'content-type: application/json' \
-d '{"tenant_id":"default"}' | jq '{status, output, annotations}'
A missing result assignment fails with mapping script produced no result.
Capture a golden and run the suite
# Approve the current output as the expectation for the active sample
curl -s -X POST "$SIRIUS/studio/workspaces/$WS/samples/<sample-id>/capture-expectation" \
-d '{"tenant_id":"default"}'
curl -s -X POST "$SIRIUS/studio/workspaces/$WS/test" \
-d '{"tenant_id":"default"}' | jq '{total, passed, failed, errored}'
curl -s "$SIRIUS/studio/workspaces/$WS/coverage"
Comparison is JSON-normalized. 2 matches 2.0. The same goldens work after you change language packs.
Promote a milestone
curl -s -X POST "$SIRIUS/studio/workspaces/$WS/milestones" \
-H 'content-type: application/json' -d '{
"tenant_id":"default",
"label":"v1.0",
"note":"first release",
"require_tests_pass":true,
"capture_baseline":true
}'
A red suite returns HTTP 422 and the failing report. Restore later with POST …/milestones/{id}/restore.
Switch language pack
curl -s -X POST "$SIRIUS/studio/workspaces/$WS/runtime-pack" \
-H 'content-type: application/json' \
-d '{"tenant_id":"default","runtime_pack":"python"}'
sirius.* does not change. Rewrite the entrypoint in the new syntax, then re-run the suite.
SQL against a connector
curl -s "$SIRIUS/studio/sql/connectors"
curl -s -X POST "$SIRIUS/studio/sql/query" \
-H 'content-type: application/json' -d '{
"tenant_id":"default",
"connector_id":"warehouse",
"sql":"select id, name from sites where region = ?",
"params":["west"],
"limit":50
}'
Never a raw DSN. Writes commit. Four in-flight queries per tenant; extras are 429 too_many_queries with Retry-After: 1 and the statement does not run.
Export and import a workspace
curl -s "$SIRIUS/studio/workspaces/$WS/export" -o normalize.studio.json
curl -s -X POST "$SIRIUS/studio/workspaces/import" --data-binary @normalize.studio.json
Bundles are signed. They carry files, samples, and expectations — not host secrets.
Python
import requests
SIRIUS = "http://localhost:8080"
s = requests.Session()
s.headers.update({"Authorization": f"Bearer {token}"})
ws = s.post(f"{SIRIUS}/studio/workspaces", json={
"tenant_id": "default",
"name": "Normalize order",
}).json()
s.put(f"{SIRIUS}/studio/workspaces/{ws['id']}/files", json={
"tenant_id": "default",
"path": "main.js",
"entrypoint": True,
"content": "result = { message: sirius.json.decode(msg.raw) };",
})
run = s.post(
f"{SIRIUS}/studio/workspaces/{ws['id']}/run",
json={"tenant_id": "default"},
).json()
print(run["status"], run.get("output"))
Run is a write (studio:write). A viewer token can list the workspace and still receive 403 on /run.