Admin Endpoints
All admin endpoints require a valid admin JWT (platform admin, tenant admin, or app admin depending on the operation).
Apps
POST /admin/apps
Create a new app.
Auth: Platform admin or tenant admin
Request:
{
"name": "My App",
"tenant_id": "tenant-uuid",
"bundle_id": "com.example.myapp",
"registration_policy": "invite",
"config": {
"allowed_providers": ["password", "google"],
"redirect_uris": ["https://myapp.com/auth/callback"],
"available_roles": ["user", "manager", "admin"],
"auto_assign_roles": ["user"],
"token_lifetime_minutes": 15,
"refresh_lifetime_days": 30,
"branding": {
"primary_color": "#9392c7",
"logo_url": null,
"logo_height": 80
}
}
}
Response (201): The created app object including id and client_secret (shown once).
PUT /admin/apps/{app_id}
Update app configuration.
Auth: Platform admin, tenant admin, or app admin (managers excluded)
Request: Partial update — only include fields to change.
{
"name": "Updated Name",
"config": {
"allowed_providers": ["password", "google", "magic_link"],
"branding": { "primary_color": "#d1001f" }
}
}
Note: Uploaded logo_data is preserved automatically when saving config without it.
POST /admin/apps/{app_id}/logo
Upload an app logo.
Auth: Platform admin, tenant admin, or app admin
Request: Multipart form data with file field (PNG, JPEG, SVG, max 2MB, resized to 256px).
POST /admin/apps/{app_id}/regenerate-secret
Generate a new client secret. Old secret is invalidated immediately.
Auth: Platform admin, tenant admin, or app admin
Response:
{ "client_secret": "new-secret-shown-once" }
Users
GET /admin/users
List all users (platform admin only).
Query Params: ?page=1&limit=50&search=email
POST /admin/users
Create a user.
Auth: Platform admin
Request:
{
"email": "user@example.com",
"display_name": "Jane Doe",
"password": "optional"
}
PUT /admin/users/{user_id}/roles
Assign roles for a user in an app.
Auth: Platform admin, tenant admin, or app admin (managers excluded)
Request:
{
"app_id": "uuid",
"roles": ["user", "admin"]
}
The user role is always included (enforced by ensure_base_role()).
POST /admin/users/{user_id}/suspend
Suspend a user's access to an app.
Auth: Platform admin, tenant admin, or app admin
Request:
{ "app_id": "uuid" }
DELETE /admin/users/{user_id}
Remove a user's enrollment from an app.
Auth: Platform admin, tenant admin, or app admin
Request:
{ "app_id": "uuid" }
PUT /admin/users/{user_id}/password
Change a user's password (admin override).
Auth: Platform admin only
Request:
{ "new_password": "new_secure_password" }
Password minimum length is enforced per the user's strictest tenant policy.
GET /admin/users/{user_id}/rate-limits
Check rate limit status for a user.
Auth: Platform admin only
Response:
{
"user_id": "uuid",
"email": "user@example.com",
"rate_limits": [
{ "label": "Login (email)", "key": "rl:login:user@example.com", "count": 4, "ttl": 583 }
]
}
POST /admin/users/{user_id}/rate-limits/clear
Clear all rate limits for a user.
Auth: Platform admin only
Invites
POST /admin/apps/{app_id}/invites
Create and optionally send an invite.
Auth: Platform admin, tenant admin, app admin, or app manager (managers restricted to user role only)
Request:
{
"app_id": "uuid",
"roles": ["user"],
"send_to_email": "invitee@example.com",
"max_uses": 1,
"expires_days": 7
}
Response:
{
"code": "ABCD1234",
"app_id": "uuid",
"roles": ["user"],
"expires_at": "2026-03-24T00:00:00Z",
"email_sent": true
}
Tenant Admin Management
POST /admin/tenants/{tenant_id}/admins
Invite a new tenant admin.
Auth: Platform admin or existing tenant admin for this tenant
Request:
{
"email": "newadmin@example.com"
}
DELETE /admin/tenants/{tenant_id}/admins/{user_id}
Remove a tenant admin. Cannot remove yourself.
Auth: Platform admin or existing tenant admin for this tenant