Platform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Models Tools & Services
Solutions
Organisations Developers Internet Service Providers Managed Service Providers AI-in-a-Box
Resources
Support Documentation Blog Downloads
Company
About Research Careers Investment Opportunities Contact
Log in

REST API

The ScaiFlow backend exposes a tenant-scoped REST API at /api/v1/* on whatever hostname your tenant deploys it under.

This is the public surface — the canvas uses it, your CI can use it, third-party tools can use it. Every endpoint that mutates requires ScaiKey authentication (or the deprecated dev-token fallback); read endpoints obey per-flow ACLs.

Base URL#

text
1
https://scaiflow.<your-domain>/api/v1

Substitute <your-domain> with whatever your tenant deploys at (scaiflow.scailabs.ai, scaiflow.acme.example, etc.).

Authentication#

Two auth flows are supported:

ScaiKey OIDC (primary)#

Bearer token from the BFF token exchange:

http
1
Authorization: Bearer <access_token>

To obtain a token from a service that already has a refresh token, use POST /v1/auth/refresh (see Auth router). For interactive browser logins, the canvas runs the OAuth Authorization Code + PKCE flow against ScaiKey directly and exchanges the code via POST /v1/auth/exchange.

Dev token (deprecated, only for POST /v1/dev/deploy)#

Shared bearer set via SCAIFLOW_API_TOKEN env at the API process. Only the legacy /v1/dev/deploy endpoint honors it. New code should use ScaiKey OIDC.

Routers#

The API is split into routers by domain. Each router page lists every endpoint with method, path, request, response, and required permissions.

Router Surface Page
Flows flow CRUD, deploy, run-tests, versions, presence, deployments ./rest-api/flows
Auth runtime config, BFF token exchange + refresh, /v1/me ./rest-api/auth
Admin ScaiKey-driven user/group sync, super_admin grants, tenant views ./rest-api/admin
Catalog per-tenant flow packages: list, publish, install, visibility ./rest-api/catalog
Tenants per-tenant ScaiGrid credentials ./rest-api/tenants
Lookups read-only proxies into ScaiQueue / ScaiBunker / ScaiGrid ./rest-api/lookups
ScaiCore events, checkpoints, invoke proxy ./rest-api/scaicore
Flow ACLs per-flow access control: list / grant / revoke ./rest-api/flow-acls
Preview live compile + validate (no persistence) ./rest-api/preview
Webhooks ScaiKey signed-webhook receiver ./rest-api/webhooks
Deploy (legacy) POST /v1/dev/deploy and POST /v1/flows/{id}/deploy ./rest-api/deploy

Permissions#

Two canonical permissions, inherited from ScaiCore:

Permission Required for
scaicore:view All read endpoints, live preview, validation, browsing catalog, watching events.
scaicore:manage All mutating endpoints, deploy, run-tests, publish catalog, resolve checkpoints, invoke.

Plus two ScaiFlow-local admin roles (stored in the ScaiFlow DB, not in ScaiKey):

  • tenant_admin — tenant-wide visibility + tenant credential management.
  • super_admin — platform-wide.

Error shape#

Errors follow the FastAPI default {"detail": ...} shape. Some endpoints return a structured detail dict for machine consumption:

jsonc
// 412 — missing tenant credentials
{
  "detail": {
    "error": "missing_credentials",
    "message": "no ScaiGrid credentials for tenant 'acme'",
    "fix": "Sign in with ScaiKey, or set this tenant's API key via POST /v1/tenants/me/scaigrid_credentials."
  }
}
jsonc
// 502 — upstream ScaiGrid auth rejected
{
  "detail": {
    "error": "scaigrid_auth",
    "message": "...",
    "fix": "Caller needs `scaicore:view` on this tenant."
  }
}

Versioning#

The API is at /v1. There is no /v2 yet. Breaking changes will bump to /v2; additive changes (new fields, new endpoints) land on /v1.

Rate limiting#

No rate limiting is enforced by ScaiFlow itself today. Upstream (ScaiGrid) may rate-limit per its own policy; ScaiFlow returns the upstream's rate-limit response unchanged.

CORS#

The canvas runs on http://localhost:5173 in dev and on its production host in prod. The API allows those origins by default; check apps/api/scaiflow_api/app.py for the exact list if you need to add another.

Updated 2026-05-18 16:05:21 View source (.md) rev 3