Feature: Expert Application
Last updated: 2026-06-04 (Pass-3 docs audit follow-up β Tavus expert application cluster shipped 2026-06-03)
The Expert Application flow is how Humanity Protocol acquires new Experts: public applicants submit a form on the marketing site, complete an asynchronous Tavus video interview, and β if their interview reviews well β are promoted by a SuperAdmin into the platform as an active Expert. It is operationally distinct from the client onboarding flow.
Three audiences interact with this feature:
- Applicants β fill the marketing form, take the Tavus interview, then wait for an outcome email.
- AMs / SuperAdmins β review applications in the unified Ops surface
(
/ops/marketing/experts/*), retry interview invites, hard-delete spam entries, approve or decline applicants. - The Tavus integration β drives the video interview, posts conversation
- transcript webhooks back to humanwork-api, and atomically transitions the
applicant to
interview_completedso the review queue can pick them up.
- transcript webhooks back to humanwork-api, and atomically transitions the
applicant to
What shippedβ
| PR | Change | Date |
|---|---|---|
| #1369 | Original expert application form, AI screening, and ops pipeline (closes #1082 β funnel: public apply form β async AI scoring β qualified / waitlisted β ops pipeline) | 2026-05-30 |
| #1478 | Tavus video interviews wired into the expert application track (closes #1083) β qualified applicants are sent a Tavus interview link instead of the legacy "approved" email | 2026-06-03 |
| #1540 | Fixed Tavus expert application integration issues β replica binding, applicant identity injected into conversational_context, conversation properties (recording + transcript callback URLs) tightened. Closes the regression that fell back to the qualified email when env was incomplete | 2026-06-03 |
| #1524 | Ops review interface for interview_completed applicants β /ops/marketing/experts gets an Interviews tab and a "Retry interview invite" action | 2026-06-03 |
| #1519 | SuperAdmin hard-delete endpoint for expert applications + trash-icon UI on the list view β lets ops scrub spam / duplicate submissions | 2026-06-03 |
| #1565 | Flow polish β send-to-interview action for waitlisted applicants, Approve transition wired to the post-interview status, LinkedIn-URL dedup on submit so resubmissions don't create new rows | 2026-06-03 |
| #1560 | 5 Expert-onboarding email templates added to EmailService (closes #1554) β application_received, interview_scheduled, application_approved, application_declined, welcome. See onboarding.md Β§Expert onboarding email templates | 2026-06-03 |
Flowβ
[Marketing site]
β
β POST /marketing/experts/application
βΌ
expert_applications row (status = pending)
β
β async AI scoring (#1369)
βΌ
status = qualified | waitlisted | rejected
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββ
β qualified β Tavus interview invite β
β (#1478, #1540) β
β email: expert.interview_scheduled β
β status β invited β
β β
β waitlisted β SuperAdmin clicks β
β "Send to interview" (#1565) β
β β same path as qualified β
ββββββββββββββββββββββββββββββββββββββββββββββββ
β
β Applicant joins Tavus call
β Tavus posts webhook β /tavus/webhooks/conversation-ended
β Atomic status transition (#1083 / #1540): invited β interview_completed
βΌ
status = interview_completed
+ tavus_conversation_id, transcript_summary,
interview_completed_at populated
β
β SuperAdmin reviews in /ops/marketing/experts (Interviews tab, #1524)
βΌ
ββββββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββ
β Promote (POST .../promote) β Decline (POST .../decline) β
β status β approved β status β rejected β
β email: expert.application_approvedβ email: expert.application_declinedβ
β + create platform user (Expert) β β
βββββ βββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββ
β
β Approved applicant logs into /workspace
βΌ
email: expert.welcome β active Expert
Status machineβ
The full set of expert_applications.status values:
| Status | Set by | Next transitions |
|---|---|---|
pending | Public submit | β qualified / waitlisted / rejected (AI scoring) |
reviewing | AI scoring in-flight | β qualified / waitlisted / rejected |
qualified | AI scoring | β invited (auto, Tavus invite sent) Β· β rejected (SA decline) |
waitlisted | AI scoring | β invited (SA send-to-interview, #1565) Β· β rejected (SA decline) Β· β approved (SA promote β legacy direct path) |
invited | System (Tavus invite sent) | β interview_completed (Tavus webhook) Β· β rejected |
interview_completed | Tavus webhook (#1540) | β approved (canonical post-interview path) Β· β rejected |
approved | SA promote | terminal β platform Expert created |
rejected | SA decline | terminal |
Allowed transitions are enforced in MarketingService.promote() /
decline() /
sendWaitlistedToInterview() /
retryInterviewInvite() β see api/src/marketing/marketing.service.ts. The
post-interview promotion path (interview_completed β approved) is described
in the service's docstring as the canonical path; promoting directly from
waitlisted remains for back-compat with applications taken before #1478
shipped.
Module locationsβ
Backend (NestJS)β
-
api/src/marketing/β applicant-facing surface (form submit, status poll, waitlist rejoin) and the coreMarketingServicethat owns theexpert_applicationsrow + status transitions.marketing.controller.tsβ publicPOST /marketing/experts/application,GET /marketing/experts/application/status,GET /marketing/experts/application/:id,POST /marketing/experts/rejoin-waitlist.marketing.service.tsβsubmitExpertApplication,sendWaitlistedToInterview(#1565),retryInterviewInvite(#1524),promote(#1565, acceptsinterview_completedas entry status),decline.entities/expert-application.entity.tsβ theexpert_applicationsrow (incl. Tavus fields added in the 1783/1784 migration series β see Schema below).
-
api/src/admin/admin-marketing-leads.controller.tsβ SuperAdmin / AM-facing Ops surface. Mounts at/admin/marketing/leads/experts/*. Live routes:Route Purpose GET /admin/marketing/leads/expertsList applicants (filterable by status β Interviews tab uses status=interview_completed)GET /admin/marketing/leads/experts/:idDetail view PATCH /admin/marketing/leads/experts/:id/statusDirect status patch (back-compat) POST /admin/marketing/leads/experts/:id/promotePromote ( interview_completedβapproved, also acceptswaitlisted/invited)POST /admin/marketing/leads/experts/:id/declineDecline β rejectedPOST /admin/marketing/leads/experts/:id/retry-inviteResend Tavus invite (#1524) POST /admin/marketing/leads/experts/:id/send-to-interviewForce waitlistedβinvited+ send Tavus invite (#1565)PATCH /admin/marketing/leads/experts/:id/thresholdAdjust per-application AI score threshold DELETE /admin/marketing/leads/experts/:idSuperAdmin hard-delete (#1519) -
api/src/tavus/tavus.controller.tsβ Tavus webhook intake.POST /tavus/webhooks/conversation-endedis the entry point that atomically transitionsinvited β interview_completed(see #1540 fix). Related webhooks:POST /tavus/webhooks/function-call,POST /tavus/webhooks/transcript-ready. Replica enumeration:GET /tavus/replicas(gated byPlatformRolesGuard).
Schemaβ
expert_applications table (TypeORM entity:
api/src/marketing/entities/expert-application.entity.ts). Tavus-track
columns were added by the following migrations (verify under
api/migrations/):
| Migration | Adds |
|---|---|
1783000000001-AddTavusFieldsToExpertApplication.ts | tavus_conversation_id, tavus_replica_id, plus the invited/interview_completed status enum values |
1783000000002-AddInterviewReminderSentField.ts | interview_reminder_sent_at β for the reminder-nudge job on stale invited applicants |
1783000000003-AddInviteSentAtToExpertApplication.ts | invite_sent_at β anchors the reminder schedule and the retry-invite cooldown |
1784000000001-AddInterviewCompletedAtToExpertApplication.ts | interview_completed_at β set by the /tavus/webhooks/conversation-ended handler |
1784000000002-AddTranscriptSummaryToExpertApplication.ts | transcript_summary (JSONB) β populated when the Tavus transcript webhook fires; surfaced in the Ops Interviews tab |
The older marketing-side migration
1746000000009-ExpertApplicationR2Urls.ts (resume / portfolio object storage)
and 1752200000010-ExpertApplicationWaitlistFields.ts (AI scoring +
waitlist) predate the Tavus track but remain in effect.
Frontendβ
- Public form:
frontend/src/app/(marketing)/apply/experts/*(and the/apply/experts/statuspoll page). - Ops surface:
frontend/src/app/ops/marketing/experts/*β list view, Interviews tab (#1524), per-application detail with Approve / Decline / Retry / Send-to-Interview / Delete actions.
The Expert workspace surface itself (
/workspace/*) is not part of this doc β it's covered by expert-workspace.md. Approved applicants only see/workspace/*after theexpert.application_approvedemail lands them on the welcome flow.
Email side effectsβ
Triggered by EmailService from MarketingService (#1560):
| Transition | Template key |
|---|---|
Submit (any pending create) | expert.application_received |
qualified / waitlisted + send-to-interview / retry-invite | expert.interview_scheduled (includes the Tavus join URL) |
promote β approved | expert.application_approved |
decline β rejected | expert.application_declined |
First successful login to /workspace | expert.welcome |
Templates live under api/src/email/templates/expert/. Copy changes go
through PR review; see onboarding.md Β§Expert onboarding email
templates.
Relatedβ
- docs/specs/tavus-integration.md β the design surface for the wider Tavus integration (replica management, conversational context, webhook signatures, cost model). The expert application is one of two surfaces consuming Tavus today (the other is the client Γ Specialist onboarding call, tracked under #1379).
- docs/decisions/tavus/ADR-0001-integration-approach.md β chosen integration shape (CVI conversations + replicas, not standalone Persona Manager).
- docs/decisions/tavus/ADR-0002-integration-test-deferral.md β why integration tests against the live Tavus API are deferred and how that's compensated.
- docs/features/onboarding.md β client-side onboarding (distinct flow); the Expert email-templates table referenced from Β§Expert onboarding email templates is the same one consumed here.
- Open follow-ups:
#1202 (wire Tavus invite into
promoteExpertApplicationfor legacy waitlisted-direct-promote β now largely subsumed by #1565), #1363 (P2 design β abstract the Tavus "management" layer that today lives partly intavus/and partly inmarketing/).