Platform Admin
Platform Setup
Step-by-step guide for SuperAdmins to bootstrap the system, create a Platform, and issue API keys.
This guide is for Teamcast SuperAdmins provisioning a new integration partner. By the end you will have a Platform, at least one Tenant under it, and a working API key ready for the partner to call the Integration API.
POST /api/v1/super-admin/auth/login. This is a separate login from the tenant admin login — use the dedicated /super-admin/login page.Step 0 — Bootstrap the First SuperAdmin
This endpoint is only available once. It is permanently disabled after the first SuperAdmin account is created.
curl -X POST https://mayaapi.teamcast.ai/api/v1/super-admin/auth/bootstrap \
-H "Content-Type: application/json" \
-d '{
"email": "superadmin@teamcast.ai",
"password": "<your_password>",
"name": "Teamcast Admin"
}'{
"id": "uuid",
"email": "superadmin@teamcast.ai",
"name": "Teamcast Admin",
"status": "ACTIVE",
"createdAt": "2026-03-20T10:00:00.000Z"
}403 Forbidden on all future calls. To add more SuperAdmin accounts, use POST /api/v1/super-admin while authenticated.Step 1 — Authenticate as SuperAdmin
curl -X POST https://mayaapi.teamcast.ai/api/v1/super-admin/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "superadmin@teamcast.ai",
"password": "<your_password>"
}'{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"expiresIn": 3600,
"user": {
"id": "uuid",
"email": "superadmin@teamcast.ai",
"type": "super-admin"
}
}Include this token as Authorization: Bearer <accessToken> on all subsequent SuperAdmin requests.
Step 2 — Create a Platform
A Platform represents an integration partner or enterprise cluster. Every Tenant must belong to exactly one Platform.
| Field | Type | Required | Constraints |
|---|---|---|---|
| name | string | Yes | Max 100 characters. Human-readable label. |
| domain | string | Yes | Valid domain name, globally unique. E.g. linkedin.com |
| settings | object | No | Free-form JSON for partner metadata (contactEmail, region, etc.) |
| allowedPermissions | string[] | No | Permission ceiling for this platform. API keys issued under this platform may only use a subset of these. Defaults to the standard Integration API set if omitted (see table below). |
curl -X POST https://mayaapi.teamcast.ai/api/v1/super-admin/platforms \
-H "Authorization: Bearer <superadmin_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "LinkedIn",
"domain": "linkedin.com",
"settings": {
"contactEmail": "api-team@linkedin.com",
"region": "us-east"
}
}'{
"id": "c2650bb0-49b5-438a-b4d0-f9049ccb9f8a",
"name": "LinkedIn",
"domain": "linkedin.com",
"status": "ACTIVE",
"settings": { "contactEmail": "api-team@linkedin.com", "region": "us-east" },
"allowedPermissions": ["interview:create", "interview:read", "interview:update", "interview:approve", "interview:delete", "tenant:read", "user:create", "user:read", "user:update", "user:delete", "webhook:read", "webhook:update"],
"createdAt": "2026-03-20T10:05:00.000Z"
}id — this is your PLATFORM_ID used in all subsequent calls. The allowedPermissions array is the ceiling — no API key issued to this platform can have permissions outside this set.Step 3 — Issue a Platform API Key
Platform API keys let the partner backend call Integration API endpoints on behalf of any of their tenants. The caller must include X-Tenant-ID on every request to identify which tenant the action applies to. Each key's permissions must be a subset of the platform's allowedPermissions.
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Human-readable label (e.g. "LinkedIn Production Key") |
| permissions | string[] | Yes | List of permission strings. Must be a subset of the platform's allowedPermissions. |
| expiresAt | ISO 8601 string | No | Key expiry date. Omit for no expiry. |
| Permission | Scope | Allows |
|---|---|---|
| interview:create | Interview | POST /integration/interviews |
| interview:read | Interview | GET /integration/interviews/:runId and /integration/rankings |
| interview:update | Interview | PATCH /integration/interviews/:runId/info and /plan/revise |
| interview:approve | Interview | POST /integration/interviews/:runId/plan/approve|reject and /assessment/approve|reject |
| interview:delete | Interview | DELETE /integration/interviews/:runId and /candidate-data |
| tenant:create | Tenant mgmt | POST /platform-admin/tenants |
| tenant:read | Tenant mgmt | GET /tenants and /tenants/:id |
| tenant:update | Tenant mgmt | PUT /platform-admin/tenants/:id |
| tenant:delete | Tenant mgmt | DELETE /platform-admin/tenants/:id |
| user:create | User mgmt | POST /users |
| user:read | User mgmt | GET /users and /users/:id |
| user:update | User mgmt | PUT /users/:id |
| user:delete | User mgmt | DELETE /users/:id |
| apikey:create | API key mgmt | POST /platform-admin/api-keys |
| apikey:read | API key mgmt | GET /platform-admin/api-keys |
| apikey:delete | API key mgmt | DELETE /platform-admin/api-keys/:id |
| webhook:read | Webhook | GET /platform-admin/webhook-config, GET /tenants/:id/webhook-config |
| webhook:update | Webhook | PUT /platform-admin/webhook-config, PATCH /platform-admin/webhook-config/{activate,deactivate}, PUT /tenants/:id/webhook-config |
curl -X POST https://mayaapi.teamcast.ai/api/v1/super-admin/platforms/c2650bb0-49b5-438a-b4d0-f9049ccb9f8a/api-keys \
-H "Authorization: Bearer <superadmin_token>" \
-H "Content-Type: application/json" \
-d '{
"name": "LinkedIn Production Key",
"permissions": [
"interview:create",
"interview:read",
"interview:update",
"interview:approve",
"interview:delete"
]
}'{
"id": "key-uuid",
"name": "LinkedIn Production Key",
"key": "sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"permissions": ["interview:create", "interview:read", "interview:update", "interview:approve", "interview:delete"],
"platformId": "c2650bb0-49b5-438a-b4d0-f9049ccb9f8a",
"createdAt": "2026-03-20T10:10:00.000Z"
}Platform Management
curl https://mayaapi.teamcast.ai/api/v1/super-admin/platforms \
-H "Authorization: Bearer <superadmin_token>"Adding More SuperAdmins
curl -X POST https://mayaapi.teamcast.ai/api/v1/super-admin \
-H "Authorization: Bearer <superadmin_token>" \
-H "Content-Type: application/json" \
-d '{
"email": "another@teamcast.ai",
"password": "<your_password>",
"name": "Second Admin"
}'Permission Ceiling Model
Every platform has an allowedPermissions ceiling set by Teamcast SuperAdmin at platform creation time. This is the maximum set of permissions any API key issued under that platform can hold.
The enforcement happens at two points:
| Where | What is checked |
|---|---|
| Key issuance (POST /api-keys) | Requested permissions must be a subset of platform.allowedPermissions — 400 if any exceed the ceiling |
| Every API call (runtime) | Guard re-reads platform.allowedPermissions and rejects keys whose permissions have been narrowed since issuance — no restart required |
tenant:create), first update allowedPermissions on the platform via PATCH /api/v1/super-admin/platforms/{id}, then issue a new API key with those permissions. Existing keys are not automatically upgraded.allowedPermissions takes effect immediately for all existing keys under that platform — no key rotation required.Setup Checklist
| Step | Endpoint | Status |
|---|---|---|
| Bootstrap first SuperAdmin | POST /super-admin/auth/bootstrap | One-time |
| SuperAdmin login | POST /super-admin/auth/login | Recurring |
| Create Platform with allowedPermissions | POST /super-admin/platforms | Per partner |
| Issue Platform API key (subset of ceiling) | POST /super-admin/platforms/{id}/api-keys | Per environment |
| Configure Platform webhook | PUT /platform-admin/webhook-config | Once per platform (covers all tenants) |
| Create first Tenant | POST /tenants (with SA token) | Per customer |
| Configure Tenant webhook (optional override) | PUT /tenants/{id}/webhook-config | Only if tenant needs a different endpoint |
| Verify health | GET /api/v1/health/ready | Before go-live |