Skip to main content

Persona Manager โ€” API reference

All endpoints are routed through the existing NestJS API and inherit:

  • JwtAuthGuard for authentication
  • OrgRlsInterceptor for Postgres-level RLS (SET LOCAL app.current_org_id)
  • OrgThrottlerGuard (global APP_GUARD) for per-org rate limits

Webhook endpoints use HMAC-SHA256 instead of JWT.

SuperAdmin: function-call libraryโ€‹

MethodPathRoles
GET/ops/personas/function-calls?kind=onboarding|reporting&includeInactive=truesuperadmin, account_manager
GET/ops/personas/function-calls/:idsuperadmin, account_manager
POST/ops/personas/function-callssuperadmin
PATCH/ops/personas/function-calls/:idsuperadmin
POST/ops/personas/function-calls/:name/versionssuperadmin
DELETE/ops/personas/function-calls/:idsuperadmin

Body shapes match TavusFunctionDefinition in api/src/tavus/tavus-function-definition.entity.ts.

Tavus catalogueโ€‹

MethodPathRoles
GET/tavus/replicassuperadmin, account_manager, client_admin, org_admin

Returns the cached (5min TTL) replica list from Tavus.

Environment Profileโ€‹

MethodPathAuth
GET/environment-profiles/:idJwtAuthGuard + service-layer org-scope check
GET/environment-profiles/by-assignment/:assignmentIdsame
PATCH/environment-profiles/:id ({ data: {...} })same
POST/environment-profiles/:id/approvesame

Meetingsโ€‹

MethodPathNotes
POST/assignments/:assignmentId/onboarding/startIdempotent. Returns { meeting, conversationUrl, created }.
POST/assignments/:assignmentId/meetingsSchedule a reporting meeting.
POST/assignments/:assignmentId/meetings/:meetingId/startStart a scheduled reporting meeting. Assembles the brief and creates the persona.
GET/assignments/:assignmentId/meetingsList meetings for an assignment.
GET/meetings/:idSingle meeting detail.

Tavus webhooksโ€‹

MethodPathHeaders
POST/tavus/webhooks/function-callTavus-Signature (or X-Tavus-Signature) = HMAC-SHA256 hex of raw body, keyed on TAVUS_WEBHOOK_SECRET.
POST/tavus/webhooks/transcript-readysame

Idempotency: keyed off event_id / idempotency_key in the body or the Tavus-Idempotency-Key header. 24-hour Redis TTL; in-memory fallback when Redis is unreachable.

Error contractโ€‹

Errors return JSON { code, message } with status codes:

CodeMeaning
tavus_unconfigured (503)TAVUS_API_KEY is unset on the API.
tavus_unauthorised (401/403)Upstream Tavus rejected the call.
tavus_not_found (404)Upstream resource missing.
tavus_conflict (409)Upstream conflict (e.g. archiving an already-deleted persona โ€” swallowed).
tavus_rate_limited (429)Upstream rate limit.
tavus_upstream_error (5xx)Anything else from Tavus.
tavus_network (502)Network-level failure reaching Tavus.
replica_not_set (409)No TAVUS_DEFAULT_REPLICA_ID configured and the request didn't override.
onboarding_in_inconsistent_state (409)A prior start crashed mid-flight; archive the row and retry.
meeting_already_terminal (409)Can't restart a completed/cancelled meeting.

The controller never leaks raw upstream payloads.

Socket.io eventsโ€‹

Namespace: /notifications (existing).

EventRoomPayload
meeting_startedorg:<orgId>{ meeting_id, kind, assignment_id }
meeting_function_callorg:<orgId>{ meeting_id, function_name, ... }
meeting_completedorg:<orgId>{ meeting_id, kind }