REST API: Lookups
Read-only proxies into ScaiQueue, ScaiBunker, and ScaiGrid. Used by the canvas so the browser never holds tenant credentials and CORS stays out of the way.
All endpoints under /api/v1/scaiqueue/*, /api/v1/scaibunker/*, /api/v1/scaigrid/*. All require scaicore:view.
Auth precedence#
The proxy resolves the upstream auth in this order (configurable via SCAIFLOW_DEPLOY_AUTH):
- Caller's ScaiKey JWT (forwarded verbatim).
- Per-tenant
sgk_*API key from ScaiVault (tenants/{tenant_id}/scaigrid_api_key). SCAIGRID_API_KEYenv var fallback (dev only).
If none are available, returns 412 missing_credentials with a fix: hint pointing the user at POST /v1/tenants/me/scaigrid_credentials.
ScaiQueue#
GET /v1/scaiqueue/scopes#
List all ScaiQueue scopes visible to the tenant.
Response:
{
"data": [
{ "id": "sc_xxx", "slug": "support",
"display_name": "Support workflows", "description": "..." }
]
}
GET /v1/scaiqueue/scopes/{scope_id}/queues#
List queues in a scope.
Response:
{
"data": [
{ "id": "q_xxx", "scope_id": "sc_xxx", "slug": "review",
"display_name": "Review queue", "consumer_mode": "fifo", "max_retries": 5 }
]
}
ScaiBunker#
GET /v1/scaibunker/bunkers#
List currently-active bunkers (running or persistent) visible to the tenant.
Response:
{
"data": [
{ "bunker_id": "bnk_xxx", "image_ref": "python-3.12",
"lifecycle": "ephemeral", "status": "ready", ... }
]
}
ScaiGrid#
GET /v1/scaigrid/models#
The tenant's frontend-model catalog from ScaiGrid. Used by the canvas Model Picker.
Response:
{
"data": [
{ "slug": "openai/gpt-4o", "display_name": "GPT-4o",
"modality": "chat", "context_window": 128000, "max_output_tokens": 16384 },
{ "slug": "scailabs/poolnoodle-omni", "display_name": "Poolnoodle Omni",
"modality": "chat", "context_window": 256000 },
{ "slug": "openai/gpt-4o-mini", "display_name": "GPT-4o mini",
"modality": "chat", "context_window": 128000 }
]
}
The proxy normalizes two upstream response envelopes:
- Native ScaiGrid
{"data": [{"slug": ...}, ...]}. - OpenAI-compat
{"object": "list", "data": [{"id": "openai/gpt-4o", "object": "model", ...}, ...]}— theidfield is mapped toslugso the canvas sees one shape.
Also tolerant of {"data": {"items": [...]}} nested-pagination wrappers some ScaiGrid deployments use.
Error shapes#
All proxies surface upstream errors as 502 Bad Gateway with a structured detail:
{
"detail": {
"error": "scaiqueue_auth",
"message": "permission_denied: need scaiqueue:view",
"fix": "Caller needs the `scaiqueue:view` permission on this tenant."
}
}
Variants:
error value |
Meaning |
|---|---|
scaiqueue_auth / scaibunker_auth / scaigrid_auth |
Upstream returned 401/403. |
scaiqueue_api / scaibunker_api / scaigrid_api |
Upstream returned a non-auth error (4xx/5xx); status + code carry the upstream's values. |
missing_credentials |
No JWT, no tenant API key configured. 412 response. |