REST API: Tenants
Per-tenant ScaiGrid credential management. One status endpoint, one mutator.
All endpoints under /api/v1/tenants/me — the caller's tenant is always derived from their ScaiKey JWT.
GET /v1/tenants/me/scaigrid_credentials#
Returns the configured status of the tenant's ScaiGrid credentials.
Response:
{
"configured": true,
"base_url": "https://scaigrid.scailabs.ai",
"masked_key": "sgk_…1234" // first 4 + last 4 chars
}
If no credentials are set, returns:
{
"configured": false,
"base_url": null,
"masked_key": null
}
No special permission required — any tenant member can see whether their tenant has credentials configured.
POST /v1/tenants/me/scaigrid_credentials#
Set or rotate the tenant's ScaiGrid credentials. Written to ScaiVault at tenants/{tenant_id}/scaigrid_api_key and tenants/{tenant_id}/scaigrid_base_url.
Body:
{
"api_key": "sgk_xxxxxxxxxxxx",
"base_url": "https://scaigrid.scailabs.ai" // optional
}
Response: 204 No Content.
tenant_admin or super_admin required.
Why this exists#
The backend can authenticate to ScaiGrid in two ways:
- User JWT (preferred) — when there's a calling user, forward their ScaiKey access token. ScaiGrid accepts it directly.
- Per-tenant API key (fallback) — when there's no user (background sync, scheduled triggers, dev-token deploys), the backend looks up the tenant's
sgk_*key from ScaiVault.
For most tenant operations the user-JWT path is enough. But some flows need the API-key fallback to be configured:
- The background ScaiKey-sync loop.
- Cron-triggered flows whose entry node is
entry_schedule. - Dev environments where the ScaiFlow API runs without a real user session.
The SCAIFLOW_DEPLOY_AUTH=user_jwt|api_key env var pins the choice for debugging — leave it unset for default precedence (JWT, then API key).
What the canvas does with this#
The toolbar's status indicator + the tenant admin's Settings page both call GET .../scaigrid_credentials. If configured: false, the canvas shows a warning + a button that opens the credential entry form.
Setting the credentials there POSTs to this endpoint — the API key isn't kept in the canvas's localStorage, just in ScaiVault.