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: Admin

ScaiKey-driven user/group sync, super_admin role management, tenant admin views.

All endpoints under /api/v1/admin. Most require super_admin (role is the ScaiFlow-local admin role, not a ScaiKey role); a few /tenant/* endpoints accept tenant_admin too.

GET /v1/admin/users#

List every user mirrored from ScaiKey.

Super admin only.

Response:

jsonc
{
  "users": [
    {
      "id": "usr_xxx",
      "tenant_id": "tnt_acme",
      "email": "alice@acme.example",
      "display_name": "Alice Johnson",
      "status": "ACTIVE",
      "admin_role": "tenant_admin",       // null | tenant_admin | super_admin
      "admin_role_source": "manual",      // null | manual | group | bootstrap
      "deleted_at": null,
      "last_synced_at": "2026-04-29..."
    }
  ]
}

POST /v1/admin/sync#

Trigger an immediate sync from ScaiKey. Same code path as the hourly background sync.

Super admin only.

Response:

jsonc
{
  "skipped_reason": null,
  "users_method": "effective_users",     // or "member_walk" (fallback path)
  "users_seen": 42,
  "users_added": 3,
  "users_undeleted": 0,
  "users_soft_deleted": 1,
  "groups_seen": 7,
  "groups_added": 0,
  "groups_undeleted": 0,
  "groups_soft_deleted": 0,
  "memberships_seen": 86,
  "memberships_added": 5,
  "memberships_soft_deleted": 2,
  "super_admin_count": 2,
  "super_admins_group_promoted": 0,
  "super_admins_group_demoted": 0,
  "duration_seconds": 1.8
}

skipped_reason is set when sync was skipped (e.g. credentials_missingSCAIKEY_BASE_URL etc. not configured).

users_method indicates which path mirrored users: effective_users (preferred, platform-tier ScaiKey credentials) or member_walk (tenant-tier fallback).

POST /v1/admin/users/{user_id}/role#

Grant an admin role to a user.

Body:

jsonc
{ "role": "tenant_admin" }   // or "super_admin"

Super admin can grant either role to anyone. Tenant admin can grant tenant_admin to users in their own tenant only.

204 No Content.

The grant is recorded with admin_role_source = "manual" — survives reconciliation (the group-derived sync won't demote a manual grant). Use the matching DELETE to revoke.

DELETE /v1/admin/users/{user_id}/role#

Revoke an admin role. Same permission rules as grant.

204 No Content.

Refuses to demote the last super_admin (would lock out platform access). Set another super_admin first.

GET /v1/admin/tenant/users#

All users in the calling tenant. Accepts tenant_admin (sees own tenant only) or super_admin (sees specified or own tenant).

Query:

  • tenant_id — (super_admin only) view a different tenant's users.

Response: same shape as /v1/admin/users but scoped.

GET /v1/admin/tenant/flows#

All flows in the calling tenant, regardless of per-flow ACLs (tenant admins have implicit admin access on every flow in their tenant).

Response:

jsonc
[
  {
    "id": "flow_xxx",
    "name": "Customer Support",
    "owner_id": "usr_alice",
    "owner_email": "alice@acme.example",
    "version": "1.0.2",
    "created_at": "2026-04-01...",
    "updated_at": "2026-04-29..."
  }
]

Used by the tenant admin UI to surface every flow in the tenant, even ones the admin doesn't have an explicit ACL on.

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