Platform Admin

Webhook Configuration

Configure platform-wide and per-tenant webhook endpoints from the Platform Admin console or via the REST API.

Platform Admins can provision webhook endpoints at two levels and inspect or test delivery without leaving the console. This page covers both the UI flow and the equivalent REST endpoints so partner integrations can automate the same operations.

Need the underlying payload format, HMAC scheme, or retry policy? See the Integration API → Webhooks reference. This page focuses on configuration only.

Resolution order

When an event fires, Teamcast picks the destination URL by first match:

PriorityLayerScopeWho configures
1interview.callbackUrlSingle interview onlyCaller of POST /integration/interviews
2TenantWebhookConfigAll interviews for one tenantTenant Admin OR Platform Admin
3PlatformWebhookConfigAll tenants under the platformPlatform Admin
Most partner integrations register at platform level and use the per-payload tenantId to route internally. Override per-tenant only when a specific customer needs a different endpoint or signing secret.

UI walkthrough — Platform webhook

Register a platform-wide endpoint

From the Platform Admin console:

StepAction
1Sign in at /login → Platform Admin tab
2Open Webhooks in the sidebar
3Enter a public HTTPS callbackUrl
4Tick the events you want delivered (empty = all events)
5Save — the signing secret is auto-generated and shown ONCE. Copy it now.
The full secret is returned only on first save (or when explicitly rotated). Subsequent reads return a masked hint (****<last4>) for verification only.

Rotate, deactivate, or remove

Re-saving with a new secret value rotates the HMAC key. Leave the field blank to keep the current one. Use Deactivate to soft-pause event delivery — the row is preserved (URL, secret, events, history) and only isActive flips to false. Saving the form again (with URL + events) registers a fresh active webhook and flips isActive back to true — this is the only path back to active in the UI; no separate “Activate” button is exposed by design. The DELETE endpoint still exists for tooling/API consumers that want a hard removal.

UI walkthrough — Per-tenant webhook

Platform Admins can manage any tenant's webhook from the same console without needing tenant-admin credentials. Strict isolation: only tenants belonging to the calling platform are editable (others return 403).

StepAction
1Open Tenants in the sidebar
2Click the webhook icon on the tenant row
3Dialog opens — fill callbackUrl, subscribed events, auto-approve, retention windows
4Save — secret auto-generated if blank; existing secret preserved on update
5Click Send Test Webhook — fires a synthetic interview.plan_generated to your URL
The Send Test Webhook button resolves the effective callback URL using the same priority order as live events and reports which layer responded. If a tenant reports “webhooks not triggering”, run this first to confirm wiring before diving into logs.

API reference

Platform-level endpoints

MethodEndpointPurpose
GET/api/v1/platform-admin/webhook-configRead current platform webhook (secret masked)
PUT/api/v1/platform-admin/webhook-configCreate or update platform webhook (re-saving an existing config reactivates it)
PATCH/api/v1/platform-admin/webhook-config/deactivateSoft-pause delivery — sets isActive=false, keeps URL/secret/events
PATCH/api/v1/platform-admin/webhook-config/activateRe-enable delivery (API/tooling only — not surfaced in the Platform Admin UI)
DELETE/api/v1/platform-admin/webhook-configHard-remove platform webhook (API only — not surfaced in the Platform Admin UI)
bash
# Create or update platform webhook
curl -X PUT https://mayaapi.teamcast.ai/api/v1/platform-admin/webhook-config \
  -H "Authorization: Bearer <PLATFORM_ADMIN_JWT>" \
  -H "Content-Type: application/json" \
  -d '{
    "callbackUrl": "https://api.acme.com/webhooks/teamcast",
    "events": [
      "interview.plan_generated",
      "interview.approved",
      "interview.rejected",
      "interview.assessment_pending"
    ]
  }'

Per-tenant endpoints (Platform Admin scope)

Platform Admin has two equivalent paths to manage a specific tenant's webhook: the dedicated /platform-admin/tenants/:tenantId/webhook-config route (recommended from a Platform Admin UI) and the shared /tenants/:id/webhook-config route (also used by Tenant Admins and Super Admins — see the Authorization section below for the caller-aware scoping rule).

MethodEndpointPurpose
GET/api/v1/platform-admin/tenants/:tenantId/webhook-configRead tenant webhook
PUT/api/v1/platform-admin/tenants/:tenantId/webhook-configCreate or update tenant webhook
DELETE/api/v1/platform-admin/tenants/:tenantId/webhook-configRemove tenant webhook
POST/api/v1/platform-admin/tenants/:tenantId/webhook-testSend synthetic test event
bash
# Configure webhook for one tenant under your platform
curl -X PUT https://mayaapi.teamcast.ai/api/v1/platform-admin/tenants/{tenantId}/webhook-config \
  -H "Authorization: Bearer <PLATFORM_ADMIN_JWT>" \
  -H "Content-Type: application/json" \
  -d '{
    "callbackUrl": "https://api.tenant.com/webhooks/teamcast",
    "events": [],
    "autoApprovePlans": false,
    "candidatePiiRetentionDays": 90,
    "assessmentRetentionDays": 365,
    "recordingRetentionDays": 30
  }'

# Send a test event (debugging)
curl -X POST https://mayaapi.teamcast.ai/api/v1/platform-admin/tenants/{tenantId}/webhook-test \
  -H "Authorization: Bearer <PLATFORM_ADMIN_JWT>" \
  -H "Content-Type: application/json" \
  -d '{ "event": "interview.plan_generated" }'
Test responses include a source field ("tenant" or "platform") so you can confirm which layer resolved the callback URL.

Authorization & isolation

All endpoints under /platform-admin/* require a Platform Admin JWT (the token issued at POST /api/v1/platform-admin/auth/login). The server enforces that the target tenant belongs to the caller's platform — a Platform Admin from Platform A cannot touch a tenant under Platform B; the API returns 403 Forbidden.

Shared /tenants/:id/webhook-config route

The tenant self-serve route /api/v1/tenants/:id/webhook-config (GET / PUT / DELETE) is also callable by Platform Admin and Super Admin, with the same scoping rule applied to the URL :id:

CallerRule applied to URL :id
super-adminAny tenant id is accepted
platform-adminTenant must belong to the caller's platform (else 403)
Tenant Admin login JWTURL :id must equal the user's tenantId (else 403)
API key + X-Tenant-IDURL :id must equal X-Tenant-ID (else 403)
OAuth tenant token / client_credentials with tenant_id claimURL :id must equal the token tenant_id claim (else 403)

Using a Platform Admin JWT against this shared route is equivalent to using the dedicated /platform-admin/tenants/:tenantId/webhook-config route — pick whichever fits your client. Cross-platform access is rejected with 403 Forbidden in both.

Configuration writes are audited. Every create, update, activate, deactivate, and delete is recorded with the actor's platformUserId and the target tenantId.

Common operations

Quiet a webhook temporarily

For the platform-level webhook, click Deactivate in the Platform Admin console (or call PATCH /platform-admin/webhook-config/deactivate). For a tenant webhook, set isActive: false on the tenant config via the API. In both cases events still fire in Maya but no HTTP delivery is attempted. Useful during planned maintenance on the receiver side.

Subscribe to a subset of events

Pass a non-empty events array. Empty array (default) delivers all events. Valid values:

json
[
  "interview.info_needed",
  "interview.info_completed",
  "interview.plan_generated",
  "interview.approved",
  "interview.rejected",
  "interview.assessment_ready",
  "interview.assessment_pending",
  "interview.modification_requested",
  "interview.cancelled"
]

Rotate the HMAC secret

Supply a new secret (min 32 chars) in the upsert payload. The previous secret immediately stops verifying. Roll receivers in lock-step to avoid dropped deliveries — or run them side-by-side for a brief overlap window.

Was this page helpful?