{"openapi":"3.1.0","info":{"title":"Ruzora Candidate CRM API","description":"Candidate pipeline, sourcing, and LinkedIn automation","version":"1.0.0"},"paths":{"/api/auth/login":{"post":{"tags":["auth"],"summary":"Login","description":"Authenticate user and return JWT tokens.","operationId":"login_api_auth_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/refresh":{"post":{"tags":["auth"],"summary":"Refresh Token","description":"Refresh JWT token — returns new access + refresh tokens.","operationId":"refresh_token_api_auth_refresh_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/logout":{"post":{"tags":["auth"],"summary":"Logout","description":"Logout — clears refresh token cookie.","operationId":"logout_api_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/me":{"get":{"tags":["auth"],"summary":"Get Current User Info","description":"Get current user info from token.","operationId":"get_current_user_info_api_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/auth/password-reset":{"post":{"tags":["auth"],"summary":"Request Password Reset","description":"Request password reset — always returns success (no email enumeration).","operationId":"request_password_reset_api_auth_password_reset_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/auth/password-reset/confirm":{"post":{"tags":["auth"],"summary":"Confirm Password Reset","description":"Reset password using valid reset token.","operationId":"confirm_password_reset_api_auth_password_reset_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasswordResetConfirm"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/accounts":{"get":{"tags":["Accounts"],"summary":"List Accounts","description":"List all LinkedIn accounts","operationId":"list_accounts_api_accounts_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Account"},"type":"array","title":"Response List Accounts Api Accounts Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Accounts"],"summary":"Add Account","description":"Add a new LinkedIn account","operationId":"add_account_api_accounts_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/accounts/{account_id}/health":{"get":{"tags":["Accounts"],"summary":"Get Account Health","description":"Get account health status","operationId":"get_account_health_api_accounts__account_id__health_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountHealth"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/accounts/{account_id}/refresh-session":{"post":{"tags":["Accounts"],"summary":"Refresh Session","description":"Trigger session refresh for account","operationId":"refresh_session_api_accounts__account_id__refresh_session_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/accounts/linkedin":{"get":{"tags":["Accounts"],"summary":"List Linkedin Accounts","description":"List all DB-backed LinkedIn accounts.","operationId":"list_linkedin_accounts_api_accounts_linkedin_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Accounts"],"summary":"Create Linkedin Account","description":"Add a new LinkedIn account to DB.","operationId":"create_linkedin_account_api_accounts_linkedin_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkedInAccountCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/accounts/linkedin/{account_id}":{"get":{"tags":["Accounts"],"summary":"Get Linkedin Account","description":"Get a single LinkedIn account.","operationId":"get_linkedin_account_api_accounts_linkedin__account_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Accounts"],"summary":"Update Linkedin Account","description":"Update a LinkedIn account (cookie refresh, status change, etc.).","operationId":"update_linkedin_account_api_accounts_linkedin__account_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkedInAccountUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Accounts"],"summary":"Delete Linkedin Account","description":"Soft-delete a LinkedIn account.","operationId":"delete_linkedin_account_api_accounts_linkedin__account_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/accounts/linkedin/{account_id}/connect-phantombuster":{"post":{"tags":["Accounts"],"summary":"Connect Phantombuster","description":"Mark account as connected to PhantomBuster.","operationId":"connect_phantombuster_api_accounts_linkedin__account_id__connect_phantombuster_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"path","required":true,"schema":{"type":"string","title":"Account Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/inbox/conversations":{"get":{"tags":["Inbox"],"summary":"List Conversations","description":"List all conversations.\n\nArgs:\n    account_id: Optional filter by account\n    use_mock: Force use of mock data (for testing)","operationId":"list_conversations_api_inbox_conversations_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"account_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Id"}},{"name":"use_mock","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Use Mock"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Conversation"},"title":"Response List Conversations Api Inbox Conversations Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/inbox/conversations/{conversation_id}/messages":{"get":{"tags":["Inbox"],"summary":"Get Messages","description":"Get all messages in a conversation.","operationId":"get_messages_api_inbox_conversations__conversation_id__messages_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"use_mock","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Use Mock"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/Message"},"title":"Response Get Messages Api Inbox Conversations  Conversation Id  Messages Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/inbox/conversations/{conversation_id}/send":{"post":{"tags":["Inbox"],"summary":"Send Message","description":"Send a message in a conversation.","operationId":"send_message_api_inbox_conversations__conversation_id__send_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendMessageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/inbox/conversations/{conversation_id}/mark-read":{"post":{"tags":["Inbox"],"summary":"Mark As Read","description":"Mark conversation as read.","operationId":"mark_as_read_api_inbox_conversations__conversation_id__mark_read_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/inbox/sync-status":{"get":{"tags":["Inbox"],"summary":"Get Sync Status","description":"Get inbox sync status.","operationId":"get_sync_status_api_inbox_sync_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyncStatusResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/inbox/sync":{"post":{"tags":["Inbox"],"summary":"Trigger Sync","description":"Manually trigger inbox sync.","operationId":"trigger_sync_api_inbox_sync_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/candidates":{"get":{"tags":["Candidates"],"summary":"List Candidates","description":"List candidates with optional filters","operationId":"list_candidates_api_candidates_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"min_score","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Min Score"}},{"name":"country","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CandidateRead"},"title":"Response List Candidates Api Candidates Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Candidates"],"summary":"Create Candidate","description":"Create a new candidate","operationId":"create_candidate_api_candidates_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Candidate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/pipeline":{"get":{"tags":["Candidates"],"summary":"Get Pipeline","description":"Get candidates grouped by pipeline stage (sourcing track only, excludes Applied)","operationId":"get_pipeline_api_candidates_pipeline_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/candidates/applications":{"get":{"tags":["Candidates"],"summary":"List Applications","description":"List candidates with status=Applied (from jobs form submissions)","operationId":"list_applications_api_candidates_applications_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/candidates/applications/{candidate_id}/accept":{"patch":{"tags":["Candidates"],"summary":"Accept Application","description":"Move an Applied candidate to Screening","operationId":"accept_application_api_candidates_applications__candidate_id__accept_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/applications/{candidate_id}/to-pipeline":{"patch":{"tags":["Candidates"],"summary":"Move Application To Pipeline","description":"Move an Applied candidate to New (pipeline first column) for outreach","operationId":"move_application_to_pipeline_api_candidates_applications__candidate_id__to_pipeline_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/applications/{candidate_id}/reject":{"patch":{"tags":["Candidates"],"summary":"Reject Application","description":"Archive an Applied candidate (not a fit)","operationId":"reject_application_api_candidates_applications__candidate_id__reject_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}":{"get":{"tags":["Candidates"],"summary":"Get Candidate","description":"Get a single candidate by ID.","operationId":"get_candidate_api_candidates__candidate_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateRead"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Candidates"],"summary":"Update Candidate","description":"Update candidate details. Auto-advances Screening → Bench when vetting criteria met.","operationId":"update_candidate_api_candidates__candidate_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Data"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/projects":{"get":{"tags":["Candidates"],"summary":"Get Candidate Projects","description":"Get all projects a candidate is participating in, with their stage in each.","operationId":"get_candidate_projects_api_candidates__candidate_id__projects_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/role-interests":{"get":{"tags":["Candidates"],"summary":"Get Candidate Role Interests","description":"Every role this candidate has applied for, newest first.\n\nPowers the multi-role chips + role-history section in the dashboard.\nEmpty list for legacy rows that pre-date the candidate_role_interests\njunction.","operationId":"get_candidate_role_interests_api_candidates__candidate_id__role_interests_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/notes":{"post":{"tags":["Candidates"],"summary":"Add Candidate Note","description":"Add a note to a candidate's activity log.","operationId":"add_candidate_note_api_candidates__candidate_id__notes_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddNoteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/status":{"patch":{"tags":["Candidates"],"summary":"Update Candidate Status","description":"Update candidate pipeline status","operationId":"update_candidate_status_api_candidates__candidate_id__status_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateStatusRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/marketing-consent":{"patch":{"tags":["Candidates"],"summary":"Update Marketing Consent","description":"Grant or revoke an engineer's consent to be pitched by MPC.\n\nPRD_MPC_2026-09 M2-4. Before this, `marketing_consent_revoked_at` was\nread by the matcher's consent gate and written by NOTHING — a candidate\nwho asked to stop being pitched could only be honoured by hand-editing\nthe database. A consent regime with no revoke path is not a consent\nregime, and this is the surface Roberto acts on when an engineer asks.\n\nREVOKING NEVER CLEARS THE ORIGINAL GRANT. `marketing_consent_at` stays,\nso the record still says what was true: they consented on that date, and\nlater withdrew it. Blanking the grant would destroy the audit trail that\nmakes the withdrawal defensible.\n\nREVOCATION IS ONE-WAY HERE. `granted=True` on an already-revoked\ncandidate is refused with a 409, because re-granting is a decision that\nneeds the engineer's own new consent, not an operator's PATCH. The\nmatcher's gate fails closed on the same asymmetry.","operationId":"update_marketing_consent_api_candidates__candidate_id__marketing_consent_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketingConsentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/outreach/queue":{"get":{"tags":["Outreach"],"summary":"Get Queue","operationId":"get_queue_api_outreach_queue_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"campaign_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign Id"}},{"name":"entity_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/outreach/bulk-add":{"post":{"tags":["Outreach"],"summary":"Bulk Add","operationId":"bulk_add_api_outreach_bulk_add_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkAddRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/outreach/approve":{"post":{"tags":["Outreach"],"summary":"Approve Items","operationId":"approve_items_api_outreach_approve_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApproveRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/outreach/approve-bulk":{"post":{"tags":["Outreach"],"summary":"Approve Bulk","operationId":"approve_bulk_api_outreach_approve_bulk_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"min_score","in":"query","required":false,"schema":{"type":"integer","default":70,"title":"Min Score"}},{"name":"campaign_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/outreach/stats":{"get":{"tags":["Outreach"],"summary":"Get Queue Stats","operationId":"get_queue_stats_api_outreach_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/outreach/daily-summary":{"get":{"tags":["Outreach"],"summary":"Get Daily Summary","operationId":"get_daily_summary_api_outreach_daily_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/outreach/{message_id}":{"patch":{"tags":["Outreach"],"summary":"Update Message","operationId":"update_message_api_outreach__message_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateMessageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/outreach/{message_id}/replied":{"patch":{"tags":["Outreach"],"summary":"Mark Replied","operationId":"mark_replied_api_outreach__message_id__replied_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"message_id","in":"path","required":true,"schema":{"type":"string","title":"Message Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ai/generate":{"post":{"tags":["AI"],"summary":"Generate Messages","description":"Generate 5 message alternatives for a candidate","operationId":"generate_messages_api_ai_generate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GenerateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/ai/refine":{"post":{"tags":["AI"],"summary":"Refine Message","description":"Refine a message based on instruction","operationId":"refine_message_api_ai_refine_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefineRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefineResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/ai/parse-resume":{"post":{"tags":["AI"],"summary":"Parse Resume","description":"Parse resume text using Claude and extract structured profile data.","operationId":"parse_resume_api_ai_parse_resume_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeParseRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeParseResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/ai/usage":{"post":{"tags":["AI"],"summary":"Log External Usage","description":"Log AI token usage from external services (chat-api, agent-service).\n\nThis endpoint is for internal service-to-service use.","operationId":"log_external_usage_api_ai_usage_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageLogRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ai/chat-log":{"post":{"tags":["AI"],"summary":"Log Chat Turns Endpoint","description":"Persist a chat conversation turn from chat-api (Sol v2 Phase 0).\n\nInternal service-to-service endpoint, same trust model as /usage.\nchat-api calls it fire-and-forget — failures here must never affect\nthe visitor's chat experience.","operationId":"log_chat_turns_endpoint_api_ai_chat_log_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatLogRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ai/chat-sessions":{"get":{"tags":["AI"],"summary":"List Chat Sessions Endpoint","description":"List recent Sol chat sessions, newest first (admin review).","operationId":"list_chat_sessions_endpoint_api_ai_chat_sessions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"since","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Since"}},{"name":"surface","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Surface"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ai/chat-sessions/{session_id}":{"get":{"tags":["AI"],"summary":"Get Chat Transcript Endpoint","description":"Full ordered transcript for one Sol chat session (admin review).","operationId":"get_chat_transcript_endpoint_api_ai_chat_sessions__session_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ai/usage/summary":{"get":{"tags":["AI"],"summary":"Get Usage Summary","description":"Get AI usage summary grouped by service and operation.","operationId":"get_usage_summary_api_ai_usage_summary_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Days"}},{"name":"service","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UsageSummaryResponse"},"title":"Response Get Usage Summary Api Ai Usage Summary Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ai/templates":{"get":{"tags":["AI"],"summary":"Get Templates","description":"Get available message templates","operationId":"get_templates_api_ai_templates_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/config":{"get":{"tags":["Admin"],"summary":"Get Config","description":"Get all feature toggles from Admin_Config","operationId":"get_config_api_admin_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/FeatureToggle"},"type":"array","title":"Response Get Config Api Admin Config Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/config/{feature}":{"patch":{"tags":["Admin"],"summary":"Update Toggle","description":"Update a feature toggle","operationId":"update_toggle_api_admin_config__feature__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"feature","in":"path","required":true,"schema":{"type":"string","title":"Feature"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateToggleRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/emergency-stop":{"post":{"tags":["Admin"],"summary":"Emergency Stop","description":"Emergency stop - disable all automation","operationId":"emergency_stop_api_admin_emergency_stop_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/activity":{"get":{"tags":["Admin"],"summary":"Get Activity","description":"Get recent activity log","operationId":"get_activity_api_admin_activity_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ActivityLog"},"title":"Response Get Activity Api Admin Activity Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/rate-limits":{"get":{"tags":["Admin"],"summary":"Get Rate Limits","description":"Get current rate limit usage across all accounts","operationId":"get_rate_limits_api_admin_rate_limits_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/stats":{"get":{"tags":["Admin"],"summary":"Get Stats","description":"Get dashboard statistics","operationId":"get_stats_api_admin_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sourcing/search":{"post":{"tags":["Sourcing"],"summary":"Search Linkedin","description":"Search LinkedIn for candidates matching criteria\n\nReturns profiles from LinkedIn search without importing them\n\nNOTE: Set enrich=true to get full profile data (skills, experience, etc.)\nWithout enrichment, you only get search snippets (~10% of data)","operationId":"search_linkedin_api_sourcing_search_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sourcing/import":{"post":{"tags":["Sourcing"],"summary":"Import Candidates","description":"Import searched candidates into database\n\nTakes candidates from search results and creates records","operationId":"import_candidates_api_sourcing_import_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sourcing/import-csv":{"post":{"tags":["Sourcing"],"summary":"Import Candidates Csv","description":"Import candidates from CSV file (PhantomBuster export). Dedup by linkedin_url, score >= 70.","operationId":"import_candidates_csv_api_sourcing_import_csv_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_import_candidates_csv_api_sourcing_import_csv_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sourcing/search-and-import":{"post":{"tags":["Sourcing"],"summary":"Search And Import","description":"Search LinkedIn and automatically import all found candidates\n\nRuns in background for larger searches","operationId":"search_and_import_api_sourcing_search_and_import_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sourcing/jobs/{job_id}":{"get":{"tags":["Sourcing"],"summary":"Get Job Status","description":"Get status of a sourcing job","operationId":"get_job_status_api_sourcing_jobs__job_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sourcing/jobs":{"get":{"tags":["Sourcing"],"summary":"List Jobs","description":"List all sourcing jobs","operationId":"list_jobs_api_sourcing_jobs_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sourcing/usage":{"get":{"tags":["Sourcing"],"summary":"Get Usage","description":"Get daily usage statistics for LinkedIn scraping","operationId":"get_usage_api_sourcing_usage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sourcing/debug":{"get":{"tags":["Sourcing"],"summary":"Debug Service","description":"Debug endpoint to check service status","operationId":"debug_service_api_sourcing_debug_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sourcing/profile":{"get":{"tags":["Sourcing"],"summary":"Get Profile","description":"Get detailed profile data for a specific LinkedIn URL","operationId":"get_profile_api_sourcing_profile_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"linkedin_url","in":"query","required":true,"schema":{"type":"string","title":"Linkedin Url"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sourcing/test-api-profile":{"get":{"tags":["Sourcing"],"summary":"Test Api Profile","description":"Test the API's get_profile method directly","operationId":"test_api_profile_api_sourcing_test_api_profile_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"public_id","in":"query","required":false,"schema":{"type":"string","default":"altamiranocd","title":"Public Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sourcing/auto-pipeline":{"post":{"tags":["Sourcing"],"summary":"Auto Pipeline","description":"Complete automation pipeline: Search → Enrich (one at a time) → Score → Import\n\nEach candidate is enriched, scored, and saved to database immediately.\nIf the pipeline crashes partway through, already-processed candidates are preserved.\nOnly candidates with score >= 70 are imported.","operationId":"auto_pipeline_api_sourcing_auto_pipeline_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sourcing/auto-pipeline-with-outreach":{"post":{"tags":["Sourcing"],"summary":"Auto Pipeline With Outreach","description":"Complete automation: Search → Enrich → Score → Import → Generate Messages → Send\n\nRuns the full auto-pipeline and then generates + sends personalized messages\nto all candidates with score >= 70","operationId":"auto_pipeline_with_outreach_api_sourcing_auto_pipeline_with_outreach_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/forms/submission":{"post":{"tags":["Forms"],"summary":"Handle Form Submission","description":"Handle form submission from ruzora.com.\n\n1. Validates input\n2. Stores in database (creates candidate record)\n3. Sends email notification\n4. Triggers scoring if resume provided\n\nReturns:\n    FormSubmissionResponse with success status and candidate_id","operationId":"handle_form_submission_api_forms_submission_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormSubmissionCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FormSubmissionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forms/submission/{candidate_id}/resume":{"patch":{"tags":["Forms"],"summary":"Attach Submission Resume","description":"Attach an uploaded résumé to a just-created application (Epic 2.6).\n\nThe public form now runs: POST /submission (row exists, emails + auto-\nsend queued) → POST /upload-resume → PATCH here. This endpoint is the\nONLY place the www apply path triggers the résumé parse.\n\nGuard: the submission response's ``resume_upload_token`` (HMAC of\ncandidate_id + issue time, 1 hour). A bare id is never enough —\n401 when the token is missing, 403 when it is forged, for another\ncandidate, or expired. Re-sending a valid token within the hour is\nallowed (the UI's retry path): each call adds a resume document and\nre-queues the parse; the newest document wins.","operationId":"attach_submission_resume_api_forms_submission__candidate_id__resume_patch","parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeAttachRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResumeAttachResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forms/hiring-lead":{"post":{"tags":["Forms"],"summary":"Handle Hiring Lead","description":"Handle hiring lead from ruzora.com home page.\nCreates a Lead record in database.\nPublic endpoint — no auth required.","operationId":"handle_hiring_lead_api_forms_hiring_lead_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HiringLeadCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forms/shortlist-request":{"post":{"tags":["Forms"],"summary":"Handle Shortlist Request","description":"Shortlist intake. For our MCP (C4a, funnel-wave PRD §1.4 tier c) a\nverified buyer token is checked first (``buyer_verification.enforce``:\nBUYER_VERIFICATION_REQUIRED, or any token that was sent); a verified\nrequest then lands in the Sol App as a role + a \"ready in Sol\" email.\nEvery other caller (website, Sol) runs exactly as before.","operationId":"handle_shortlist_request_api_forms_shortlist_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShortlistRequestCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forms/bench-preview":{"post":{"tags":["Forms"],"summary":"Handle Bench Preview","description":"Read-only pre-gate bench preview (Sol homepage hero, PRD §5.1b).\n\nRuns the SAME matching as ``/shortlist-request`` — role → atoms, one\nresolved skill request, the strict vetted filter, the ranker, the blind\n``serialize_cards`` allowlist — and returns::\n\n    {\"status\": \"ready\" | \"preview\" | \"sourcing\",\n     \"match_count\": int,            # vetted_matching_required\n     \"cards\": [...at most 3 blind cards...]}\n\n``cards`` is the SAME shape as ``shortlist_candidates`` on the intake\nresponse, so www renders both through one component.\n\nWhat this endpoint does NOT do, by contract: no lead, no publish, no\nmagic-link token, no Slack, no email, no exposure-log row — no write of\nany kind. Public and anonymous, so it carries its own per-IP limit on\ntop of the chat-api session limits. Sol calls it once, only after role +\nstack are known; the model never learns bench numbers any other way.","operationId":"handle_bench_preview_api_forms_bench_preview_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BenchPreviewRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forms/shortlist-request/{lead_id}/proposal.pdf":{"get":{"tags":["Forms"],"summary":"Get Shortlist Proposal Pdf","description":"Public download for the savings proposal PDF tied to a shortlist lead.\nGate: lead.id (UUID — unguessable) + Source must be 'request_shortlist_form'.\nOther lead types are 404'd to avoid leaking unrelated leads via this route.","operationId":"get_shortlist_proposal_pdf_api_forms_shortlist_request__lead_id__proposal_pdf_get","parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","title":"Lead Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forms/newsletter-subscribe":{"post":{"tags":["Forms"],"summary":"Handle Newsletter Subscribe","description":"Footer newsletter opt-in (\"5-Minute LATAM Hiring Brief\").\nCreates a minimal Lead (source='newsletter') and enrolls it in the\n'newsletter' nurture sequence. Personal domains are accepted — a\nnewsletter opt-in is top-of-funnel, not a shortlist gate.\n\nDedupe: if a lead already exists for this email we return success\nwithout touching it — never downgrade a real sales lead to a\nnewsletter subscriber, and never restart someone's nurture state.","operationId":"handle_newsletter_subscribe_api_forms_newsletter_subscribe_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NewsletterSubscribeCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forms/sol-degraded":{"post":{"tags":["Forms"],"summary":"Handle Sol Degraded","description":"Capture a lead from a chat surface whose assistant is unavailable.\n\nPublic endpoint — no auth. Requires only ``email``; everything else is\nwhat the widget already holds client-side. Upserts the lead (source\n``sol_degraded``), persists the transcript into chat_sessions/chat_turns\n(same tables chat-api mirrors into), and pings Slack as a hot lead.","operationId":"handle_sol_degraded_api_forms_sol_degraded_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SolDegradedCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forms/factory-inquiry":{"post":{"tags":["Forms"],"summary":"Handle Factory Inquiry","description":"Handle factory project inquiry from ruzora.com/factory.\nCreates a Lead record tagged as factory inquiry.\nPublic endpoint — no auth required.","operationId":"handle_factory_inquiry_api_forms_factory_inquiry_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactoryInquiryCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forms/submissions":{"get":{"tags":["Forms"],"summary":"List Submissions","description":"List recent form submissions (for admin).","operationId":"list_submissions_api_forms_submissions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forms/submissions/{submission_id}":{"get":{"tags":["Forms"],"summary":"Get Submission","description":"Get a specific submission by ID.","operationId":"get_submission_api_forms_submissions__submission_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"submission_id","in":"path","required":true,"schema":{"type":"string","title":"Submission Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/forms/upload-resume":{"post":{"tags":["Forms"],"summary":"Upload Resume","description":"Public resume upload (job form + chat widget). No auth required.\n\nAccepts PDF and Word documents (max 10MB).\nStores in R2 and returns the file URL.\n\n``candidate_id`` (optional form field) is sent by the job form, which\nnow creates the candidate BEFORE uploading (Epic 2.6). It is used only\nto make the storage-failure Slack alert actionable — the applicant is\nalready saved, Roberto just has to chase the CV. Never trusted for\nanything else.","operationId":"upload_resume_api_forms_upload_resume_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_resume_api_forms_upload_resume_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/nurture/process":{"post":{"tags":["Nurture","nurture"],"summary":"Process Pending Nurture","description":"Process all leads with pending nurture emails.\nCalled by Vercel Cron or manually.\nNo auth required — idempotent and safe to call repeatedly.","operationId":"process_pending_nurture_api_nurture_process_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/nurture/discount-codes/{code}":{"get":{"tags":["Nurture","nurture"],"summary":"Validate Discount Code","description":"Validate a discount code before a Deal/Pilot is signed.\n\nReturns valid=False with a reason ('not_found' | 'expired' | 'already_used')\nrather than 4xx so the dashboard can render a precise error inline.\nLead context is included on success for the rep to confirm the lead.","operationId":"validate_discount_code_api_nurture_discount_codes__code__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscountValidateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/nurture/discount-codes/{code}/redeem":{"post":{"tags":["Nurture","nurture"],"summary":"Redeem Discount Code","description":"Mark a discount code as redeemed. Single-use — second redemption returns 409.\nOptional `deal_id` is recorded in the audit log for cross-reference but is\nnot enforced as a FK (Deal/Pilot model lives elsewhere).","operationId":"redeem_discount_code_api_nurture_discount_codes__code__redeem_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string","title":"Code"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscountRedeemRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscountRedeemResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/nurture/discount-report":{"get":{"tags":["Nurture","nurture"],"summary":"Discount Report","description":"Rolling discount-code activity report for CRM dashboard / weekly Slack.\n\n`days` controls the window for \"issued\" — redemptions are counted in\nthe same window, but a code can be redeemed outside its issue window\nso we report on it whenever the redemption itself falls in the window.","operationId":"discount_report_api_nurture_discount_report_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":7,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DiscountReportResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/outbound/enroll-tick":{"post":{"tags":["Outbound","outbound"],"summary":"Enroll Tick","description":"Run one Instantly enrollment tick.\n\nCalled by the enrollment-cron GitHub Action every 30 minutes (and safe\nto call manually to drain the queue). Returns the tick's stats dict so\nthe cron log shows exactly what happened.","operationId":"enroll_tick_api_outbound_enroll_tick_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Enroll Tick Api Outbound Enroll Tick Post"}}}}}}},"/api/outbound/enrich-tick":{"post":{"tags":["Outbound","outbound"],"summary":"Enrich Tick","description":"Run one AI-opener enrichment tick (LeadEnrichmentService.run_tick).\n\nDriven by ``.github/workflows/enrichment-cron.yml`` (prod, every 15 min).\nThis REPLACES the in-process APScheduler ``IntervalTrigger(minutes=15)``\njob ``enrich_pending_leads``: interval triggers inside crm-api reset on\nevery Railway replica restart and silently never fire (2026-08-18\nenrollment stall), and enrichment had already frozen once for two weeks\n(Aug 4-18) with nothing visibly wrong. An external cron fails LOUDLY in\nGitHub Actions instead.\n\nAUTHED with X-Cron-Token, unlike ``/enroll-tick``: every call spends\nmoney (Anthropic + enrichment providers). The daily budget breaker would\ncap the damage, but an anonymous caller could still burn the whole daily\nbudget in a few requests and starve the real tick.\n\nGates — all unchanged from the scheduler path:\n  * ``OUTREACH_ENABLED`` (settings.outreach_enabled) — the scheduler's\n    master switch; when false the in-process job was never registered, so\n    this endpoint no-ops too.\n  * DB feature flag ``outbound_enrichment_enabled`` (kill switch),\n    ``OUTBOUND_ENRICHMENT_TICK_ENABLED`` env, and the fail-closed daily\n    budget breaker ``OUTBOUND_ENRICHMENT_DAILY_BUDGET_CENTS`` — all\n    enforced inside run_tick.\n  * Concurrency: leads are claimed with ``FOR UPDATE SKIP LOCKED`` and\n    flipped to ``in_progress`` (db.claim_leads_for_enrichment), so an\n    overlapping manual call or a slow previous tick can never enrich the\n    same lead twice.","operationId":"enrich_tick_api_outbound_enrich_tick_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Enrich Tick Api Outbound Enrich Tick Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/outbound/mpc-tick":{"post":{"tags":["Outbound","outbound"],"summary":"Mpc Tick","description":"Run one MPC pass: discover → score → assign → lead.\n\nCHUNKED (``max_postings`` set — what mpc-cron.yml sends): the first call\n(no ``cursor``) runs the discovery stages and returns ``next_cursor``;\neach following call passes that cursor back and matches up to\n``max_postings`` postings inside a time budget, until ``remaining`` is\n0. Each call fits well inside Railway's 5-minute request limit, which\nthe single call blew on 7 of 8 runs Sep 23 - Oct 1. See\nthe matcher's ``run_tick`` docstring. Without ``max_postings`` this is the\nold single call, unchanged.\n\nDriven by ``.github/workflows/mpc-cron.yml`` (external, weekdays). Never\nan in-process scheduler — an interval trigger inside crm-api starves on\nephemeral Railway replicas, which is what silently froze enrollment for\ntwo days in August while every gate read healthy.\n\nAUTHED with X-Cron-Token, unlike ``/enroll-tick`` above. An earlier\nversion copied that endpoint's no-auth justification, which was wrong:\n``/enroll-tick`` takes NO PARAMETERS and drains a pre-existing queue,\nbuying nothing. This one takes ``limit``, which feeds\n``cap = limit or daily_send_cap()`` and therefore overrides\nMPC_DAILY_SEND_CAP entirely, and it spends TheirStack, Hunter and\nAnthropic credits on every call. An anonymous POST could have drained\nthe monthly TheirStack plan in ~50 requests. ``limit`` is now bounded\nas well; two guards, because the blast radius is the shared\nruzora.com sending domain that every outbound channel rides on.\n\n``dry_run=true`` returns the plan without creating leads or writing the\nledger — the batch-approval surface.\n\nNOTE: this creates leads. It does not send. The existing enrollment tick\npicks them up and resolves ``instantly_campaign_mpc``; with that flag\nunset, nothing goes out.","operationId":"mpc_tick_api_outbound_mpc_tick_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_mpc_tick_api_outbound_mpc_tick_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Mpc Tick Api Outbound Mpc Tick Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/outbound/heartbeat":{"post":{"tags":["Outbound","outbound"],"summary":"Outbound Heartbeat","description":"Post the daily outbound heartbeat to #sales-signals.\n\n``once_per_day=true`` (sent by both schedulers — the Railway\ncron-scheduler primary and the GitHub backup) makes the post idempotent\nper UTC day: the first caller atomically claims today's date in\n``feature_flags`` and posts; later callers get 200 with\n``skipped=\"already_posted_today\"``. A failed Slack post releases the\nclaim so the other scheduler can retry.\n\nDriven once a day by ``.github/workflows/outbound-heartbeat-cron.yml``.\nLeads created / enrolled / replied, positive intents, queue size and the\nstate of every send gate — with a :rotating_light: line for a\nzero-enrolled day or any gate that is off. See\n``outbound_heartbeat_service`` for why a heartbeat and not another alert.\n\nAUTHED with X-Cron-Token: the response carries per-source lead counts\nand the gate configuration, and an anonymous caller could spam the\nsales channel. ``dry_run=true`` returns the rendered message without\nposting it. A real run whose Slack post fails returns 502 (body still\ncarries the rendered text) so the cron job fails loudly.","operationId":"outbound_heartbeat_api_outbound_heartbeat_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Body_outbound_heartbeat_api_outbound_heartbeat_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Outbound Heartbeat Api Outbound Heartbeat Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/outbound/vendor-rescue/findings":{"post":{"tags":["Outbound","outbound"],"summary":"Vendor Rescue Findings","description":"Submit the weekly sweep's findings. Same gates as the cron stage.","operationId":"vendor_rescue_findings_api_outbound_vendor_rescue_findings_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VendorRescueFindingsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Vendor Rescue Findings Api Outbound Vendor Rescue Findings Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/outbound/vendor-rescue/queue":{"get":{"tags":["Outbound","outbound"],"summary":"Vendor Rescue Queue","description":"Leads awaiting activation, targets held for review, vendor alerts.\n\nAuthed, unlike /mpc-results: it returns names and email addresses.","operationId":"vendor_rescue_queue_api_outbound_vendor_rescue_queue_get","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Vendor Rescue Queue Api Outbound Vendor Rescue Queue Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/outbound/vendor-rescue/dismiss":{"post":{"tags":["Outbound","outbound"],"summary":"Vendor Rescue Dismiss","description":"Close review items / alerts so next week's session does not repeat them.","operationId":"vendor_rescue_dismiss_api_outbound_vendor_rescue_dismiss_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VendorRescueDismissRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Vendor Rescue Dismiss Api Outbound Vendor Rescue Dismiss Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/outbound/cv-alumni/mentions":{"post":{"tags":["Outbound","outbound"],"summary":"Cv Alumni Mentions","description":"Sync companies extracted from candidates' work history (vp-data\ncv_alumni.py). Each candidate's mentions are REPLACED, so re-sending is\nidempotent and an edited CV can't leave stale mentions behind.","operationId":"cv_alumni_mentions_api_outbound_cv_alumni_mentions_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CvAlumniMentionsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Cv Alumni Mentions Api Outbound Cv Alumni Mentions Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/outbound/capabilities":{"get":{"tags":["Outbound","outbound"],"summary":"Outbound Capabilities","description":"Deploy + config preflight for local sourcing scripts (daily_wave.py\nrefuses to buy cv_alumni leads unless this lists cv_alumni).","operationId":"outbound_capabilities_api_outbound_capabilities_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Outbound Capabilities Api Outbound Capabilities Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/outbound/mpc-results":{"get":{"tags":["Outbound","outbound"],"summary":"Mpc Results","description":"Read back what MPC actually did. Board Round 2 #26, tech design M4-15.\n\nWithout this the data accumulates in mpc_pitches and nobody can look at\nit: rows, and no answer.\n\nRead in this order:\n  1. rank_distribution — is the matcher better than chance, and does\n     anyone ever click past rank 2? This settles the 3-vs-5 question\n     without splitting traffic.\n  2. by_arm.avg_cards — the VALIDITY check. If the challenger arm\n     cannot fill its card count, a null result is the harness's fault.\n  3. guardrails — bounces and opt-outs. ruzora.com carries every\n     outbound channel, so this stops the experiment on its own.\n  4. coverage — PRD §6.1's independent kill rule: below 50% the\n     assignment logic is broken however good the reply rate looks.\n\nRead-only. No auth, matching the ticks above: it exposes counts and\nrates, never a candidate name, a company, or an email address.","operationId":"mpc_results_api_outbound_mpc_results_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":90,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Mpc Results Api Outbound Mpc Results Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/assessments/grading-retry-tick":{"post":{"tags":["Assessments","Assessments"],"summary":"Grading Retry Tick","description":"One sweep. Returns per-table counts so the cron log shows what happened.","operationId":"grading_retry_tick_api_assessments_grading_retry_tick_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Grading Retry Tick Api Assessments Grading Retry Tick Post"}}}}}}},"/api/qualify":{"post":{"tags":["Qualify"],"summary":"Qualify","description":"Public endpoint — gates cold inbound traffic before the calendar.","operationId":"qualify_api_qualify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualifySubmission"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualifyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/idea-read/prompt":{"get":{"tags":["Idea Read"],"summary":"Get Prompt","description":"The copy-path prompt and the published bands. Public, cacheable.","operationId":"get_prompt_api_idea_read_prompt_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/idea-read/session":{"post":{"tags":["Idea Read"],"summary":"Start Session","operationId":"start_session_api_idea_read_session_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/idea-read/turn":{"post":{"tags":["Idea Read"],"summary":"Turn","operationId":"turn_api_idea_read_turn_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TurnBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/idea-read/email":{"post":{"tags":["Idea Read"],"summary":"Set Email","operationId":"set_email_api_idea_read_email_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/idea-read/paste":{"post":{"tags":["Idea Read"],"summary":"Paste","operationId":"paste_api_idea_read_paste_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PasteBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/idea-read/{read_id}":{"get":{"tags":["Idea Read"],"summary":"Get Read","operationId":"get_read_api_idea_read__read_id__get","parameters":[{"name":"read_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Read Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/idea-read/{read_id}/report.pdf":{"get":{"tags":["Idea Read"],"summary":"Get Pdf","operationId":"get_pdf_api_idea_read__read_id__report_pdf_get","parameters":[{"name":"read_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Read Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/lead-magnets/{kind}":{"post":{"tags":["Lead Magnets"],"summary":"Request Lead Magnet","operationId":"request_lead_magnet_api_lead_magnets__kind__post","parameters":[{"name":"kind","in":"path","required":true,"schema":{"type":"string","title":"Kind"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pseo/dashboard":{"get":{"tags":["pSEO"],"summary":"Get Dashboard","description":"The 5-number summary feeding the CRM dashboard / Friday calendar task.","operationId":"get_dashboard_api_pseo_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/pseo/runs":{"get":{"tags":["pSEO"],"summary":"List Runs","description":"Recent generation runs — supports filtering by status (draft / live / escalated).","operationId":"list_runs_api_pseo_runs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/GenerationRunRow"},"title":"Response List Runs Api Pseo Runs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pseo/eligible-engineers":{"get":{"tags":["pSEO"],"summary":"Eligible Engineers","description":"Top engineers currently eligible for pSEO surface. Mirrors the scoring\nquery in tools/pseo/bench_sampler.py without the stack filter (this is\nthe all-stacks view Roberto uses to spot any candidate he wants to veto).","operationId":"eligible_engineers_api_pseo_eligible_engineers_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":30,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EligibleEngineer"},"title":"Response Eligible Engineers Api Pseo Eligible Engineers Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/pseo/eligible-engineers/{candidate_id}/veto":{"post":{"tags":["pSEO"],"summary":"Veto Engineer","description":"Flip is_seo_excluded on a candidate. POST {excluded: true} to veto,\nPOST {excluded: false} to un-veto.","operationId":"veto_engineer_api_pseo_eligible_engineers__candidate_id__veto_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VetoPayload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Veto Engineer Api Pseo Eligible Engineers  Candidate Id  Veto Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/pseo/escalate":{"post":{"tags":["pSEO Internal"],"summary":"Escalate To Slack","description":"Receives the orchestrator's 3×-failure payload and forwards to Slack\nvia the bot token (which is in this service's env, not the orchestrator's).","operationId":"escalate_to_slack_api_internal_pseo_escalate_post","parameters":[{"name":"x-internal-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Internal-Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EscalatePayload"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Escalate To Slack Api Internal Pseo Escalate Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/inbound-metrics/dashboard":{"get":{"tags":["Inbound Metrics"],"summary":"Get Inbound Dashboard","description":"Track A acquisition metrics for one dashboard view.\n\n`view` ∈ total | staff_aug | factory. `weeks` is the look-back window,\nclamped to 1-52.","operationId":"get_inbound_dashboard_api_inbound_metrics_dashboard_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"view","in":"query","required":false,"schema":{"type":"string","default":"total","title":"View"}},{"name":"weeks","in":"query","required":false,"schema":{"type":"integer","default":12,"title":"Weeks"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Inbound Dashboard Api Inbound Metrics Dashboard Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/assessments":{"get":{"tags":["Assessment Metrics"],"summary":"Get Assessments Dashboard","description":"Funnel + pass-rate dashboard, fully scoped to the `days` window.\n\nA candidate_interviews / candidate_coding_assessments row is \"in the\nwindow\" if its `sent_at` falls within the last `days` days. Every\nmetric on the dashboard rolls up from this windowed set.","operationId":"get_assessments_dashboard_api_analytics_assessments_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Assessments Dashboard Api Analytics Assessments Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/candidate-funnel":{"get":{"tags":["Candidate Funnel"],"summary":"Get Candidate Funnel","operationId":"get_candidate_funnel_api_analytics_candidate_funnel_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":0,"description":"0 = all-time","default":30,"title":"Days"},"description":"0 = all-time"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Candidate Funnel Api Analytics Candidate Funnel Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/analytics/vetting-outcomes":{"get":{"tags":["Vetting Outcomes"],"summary":"Get Vetting Outcomes","operationId":"get_vetting_outcomes_api_analytics_vetting_outcomes_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"months","in":"query","required":false,"schema":{"type":"integer","maximum":120,"minimum":0,"description":"0 = all-time","default":12,"title":"Months"},"description":"0 = all-time"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Vetting Outcomes Api Analytics Vetting Outcomes Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/bulk/send-live-screen-invite":{"post":{"tags":["Candidate Meetings","candidate-meetings"],"summary":"Bulk Send Live Screen Invite","description":"Send live-screen invites to many candidates in one call.\n\nEach candidate is processed independently:\n  - Eligibility checked per-candidate (same rules as single endpoint)\n  - INSERT + email send per-candidate\n  - Per-item failures DO NOT abort the batch — they show up under\n    `skipped` with a reason\n\nCap is 50 ids per call (enforced by the Pydantic schema). Processing\nruns sequentially because SQLAlchemy AsyncSession is single-threaded.","operationId":"bulk_send_live_screen_invite_api_candidates_bulk_send_live_screen_invite_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkSendLiveScreenInviteRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BulkSendLiveScreenInviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/candidates/{candidate_id}/live-screen-meeting/{meeting_id}/mark-held":{"post":{"tags":["Candidate Meetings","candidate-meetings"],"summary":"Mark Held","description":"Recruiter clicks 'Mark held' after the live screen actually happened.\n\nOnly flips a meeting in status='scheduled' → 'held'. Returns 404 if\nno matching row (wrong id, wrong candidate, or already held/cancelled).","operationId":"mark_held_api_candidates__candidate_id__live_screen_meeting__meeting_id__mark_held_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}},{"name":"meeting_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Meeting Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/mark-vetted":{"post":{"tags":["Candidate Meetings","candidate-meetings"],"summary":"Mark Vetted","description":"Flip candidates.status to 'Vetted' — they've cleared internal vetting.\n\nGating rule: candidate must have at least one live-screen meeting in\nstatus='held'. Returns 404 if the candidate doesn't exist, 422 if no\nheld meeting exists yet.","operationId":"mark_vetted_api_candidates__candidate_id__mark_vetted_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Mark Vetted Api Candidates  Candidate Id  Mark Vetted Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/live-screen-queue/eligible":{"get":{"tags":["Candidate Meetings","candidate-meetings"],"summary":"List Live Screen Eligible","description":"Candidates ready for a live-screen invite. Powers the bulk-send UI.\n\nFilters: passed AI interview (>= 3.0), has email, not archived, no\nactive candidate_meetings row. Ordered by interview score descending.","operationId":"list_live_screen_eligible_api_live_screen_queue_eligible_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EligibleCandidateView"},"title":"Response List Live Screen Eligible Api Live Screen Queue Eligible Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/live-screen-meeting":{"get":{"tags":["Candidate Meetings","candidate-meetings"],"summary":"Get Latest Live Screen Meeting","description":"Return the candidate's most recent `live_screen` meeting, or null.\n\nUsed by the recruiter UI to render the candidate's current state\n(invited / scheduled / held / cancelled / expired) and to gate the\n\"Send invite\" button.","operationId":"get_latest_live_screen_meeting_api_candidates__candidate_id__live_screen_meeting_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/LiveScreenMeetingView"},{"type":"null"}],"title":"Response Get Latest Live Screen Meeting Api Candidates  Candidate Id  Live Screen Meeting Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/send-live-screen-invite":{"post":{"tags":["Candidate Meetings","candidate-meetings"],"summary":"Send Live Screen Invite","description":"Send a live-screen Cal.com booking link to a single candidate.\n\nGating rules:\n  404 — candidate doesn't exist\n  400 — candidate has no email on file\n  422 — candidate hasn't passed the AI interview (>= 3.0)\n  409 — an active live-screen meeting already exists for this candidate","operationId":"send_live_screen_invite_api_candidates__candidate_id__send_live_screen_invite_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendLiveScreenInviteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tasks":{"get":{"tags":["Tasks"],"summary":"List Tasks","description":"List tasks with optional filters. Does NOT expand recurrence — use\n/week or /month for calendar views.","operationId":"list_tasks_api_tasks_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO date filter","title":"Date"},"description":"ISO date filter"},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"pending|done|skipped","title":"Status"},"description":"pending|done|skipped"},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"marketing|outbound|founder|ops|...","title":"Domain"},"description":"marketing|outbound|founder|ops|..."},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"social_post|admin|outbound|...","title":"Category"},"description":"social_post|admin|outbound|..."},{"name":"task_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"(deprecated) use category","title":"Task Type"},"description":"(deprecated) use category"},{"name":"assignee_kind","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"user|agent|unassigned","title":"Assignee Kind"},"description":"user|agent|unassigned"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Tasks"],"summary":"Create Task","description":"Create a single task.","operationId":"create_task_api_tasks_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tasks/today":{"get":{"tags":["Tasks"],"summary":"Get Today Tasks","description":"Get tasks scheduled for today (including any recurrence occurrences\nthat land on today).","operationId":"get_today_tasks_api_tasks_today_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tasks/week":{"get":{"tags":["Tasks"],"summary":"Get Week Tasks","description":"Get tasks for a 7-day week view with recurrence expanded inline.","operationId":"get_week_tasks_api_tasks_week_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"start","in":"query","required":true,"schema":{"type":"string","description":"Week start date: 2026-04-02","title":"Start"},"description":"Week start date: 2026-04-02"},{"name":"end_override","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"(internal) explicit end","title":"End Override"},"description":"(internal) explicit end"},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tasks/month":{"get":{"tags":["Tasks"],"summary":"Get Month Overview","description":"Get every task occurrence in a month, with recurrence expanded.","operationId":"get_month_overview_api_tasks_month_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"month","in":"query","required":true,"schema":{"type":"string","description":"Month: 2026-04","title":"Month"},"description":"Month: 2026-04"},{"name":"domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tasks/{task_id}":{"patch":{"tags":["Tasks"],"summary":"Update Task","description":"Update a task — mark done, edit, reassign, etc.","operationId":"update_task_api_tasks__task_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Tasks"],"summary":"Delete Task","description":"Delete a task.","operationId":"delete_task_api_tasks__task_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/tasks/import":{"post":{"tags":["Tasks"],"summary":"Bulk Import Tasks","description":"Bulk import tasks (e.g., from social media calendar).","operationId":"bulk_import_tasks_api_tasks_import_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__routers__tasks__BulkImport"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/marketing-tasks":{"get":{"tags":["Marketing Tasks (deprecated)"],"summary":"List Tasks","operationId":"list_tasks_api_marketing_tasks_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"date","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Date"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"task_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Marketing Tasks (deprecated)"],"summary":"Create Task","operationId":"create_task_api_marketing_tasks_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketingTaskCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/marketing-tasks/week":{"get":{"tags":["Marketing Tasks (deprecated)"],"summary":"Get Week Tasks","operationId":"get_week_tasks_api_marketing_tasks_week_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"start","in":"query","required":true,"schema":{"type":"string","title":"Start"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/marketing-tasks/month":{"get":{"tags":["Marketing Tasks (deprecated)"],"summary":"Get Month Overview","description":"Per-day summary for a month, with recurrence expanded inline.\n\nOld shape returned a raw `GROUP BY scheduled_date, status, category` —\nthat misses biweekly/monthly occurrences whose anchor lives in an\nearlier month. We now pull recurring + one-shot rows, expand\nin-process, then aggregate to the same { date, status, task_type, count }\nshape the legacy UI expects.","operationId":"get_month_overview_api_marketing_tasks_month_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"month","in":"query","required":true,"schema":{"type":"string","title":"Month"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/marketing-tasks/{task_id}":{"patch":{"tags":["Marketing Tasks (deprecated)"],"summary":"Update Task","operationId":"update_task_api_marketing_tasks__task_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MarketingTaskUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Marketing Tasks (deprecated)"],"summary":"Delete Task","operationId":"delete_task_api_marketing_tasks__task_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"task_id","in":"path","required":true,"schema":{"type":"string","title":"Task Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/marketing-tasks/import":{"post":{"tags":["Marketing Tasks (deprecated)"],"summary":"Bulk Import Tasks","operationId":"bulk_import_tasks_api_marketing_tasks_import_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__routers__marketing_tasks__BulkImport"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/linkedin/pipeline":{"post":{"tags":["LinkedIn Pipeline"],"summary":"Run Pipeline","description":"Execute the complete LinkedIn automation pipeline.\n\nFlow:\n1. Search LinkedIn for candidates\n2. Score all candidates (rule-based)\n3. Save to database with overall_score\n4. Filter by score >= 70\n5. Send outreach messages (if enabled)\n\nArgs:\n    request: Pipeline configuration\n\nReturns:\n    PipelineResponse with execution stats\n\nExample:\n    POST /api/linkedin/pipeline\n    {\n        \"category\": \"devops\",\n        \"limit\": 25,\n        \"outreach_limit\": 10,\n        \"dry_run\": false\n    }","operationId":"run_pipeline_api_linkedin_pipeline_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipelineRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PipelineResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/agentic/run-pipeline":{"post":{"tags":["Agentic"],"summary":"Run Pipeline","description":"Run the agentic enrichment pipeline with Claude Tool Use.\n\nThe orchestrator loads SKILL.md from app/skills/<skill>/ and uses\nthe provided prompt as the user message. Claude then orchestrates\ntool calls (VP CLI, CRM import) until completion.\n\nThe founder's JWT is passed to tools that call back into the CRM.","operationId":"run_pipeline_api_agentic_run_pipeline_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RunPipelineRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/agentic/enrich-leads":{"post":{"tags":["Agentic"],"summary":"Enrich Leads","description":"Convenience endpoint: enrich ONE lead via the enrich-leads skill.\n\nShorthand for the common 'enrich this 1 LinkedIn profile' case. Internally\ncalls /run-pipeline with a formatted agent prompt.","operationId":"enrich_leads_api_agentic_enrich_leads_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichLeadsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/linkedin-accounts/refresh-cookie":{"post":{"tags":["LinkedIn Accounts"],"summary":"Refresh Cookie","description":"Push a fresh LinkedIn cookie to all PhantomBuster phantoms.\n\nFlow:\n1. For each phantom (from env vars): GET current config via PB /agents/fetch\n2. Update identities[0].sessionCookie + identities[0].userAgent\n3. POST back via PB /agents/save\n4. Return per-phantom result\n\nIn Mode A (UI paste), founder calls this from /settings/linkedin-accounts.\nIn Mode B (Playwright auto-refresh, future), a background job calls this.","operationId":"refresh_cookie_api_linkedin_accounts_refresh_cookie_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshCookieRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshCookieResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/linkedin-accounts/cookie-health":{"get":{"tags":["LinkedIn Accounts"],"summary":"Cookie Health","description":"Report current cookie status for all configured phantoms.\n\nReturns for each phantom:\n  {\n    agent_id, phantom_name, valid, last_end_type, error\n  }","operationId":"cookie_health_api_linkedin_accounts_cookie_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/phantombuster/webhook":{"post":{"tags":["PhantomBuster Webhook"],"summary":"Handle Phantom Webhook","description":"Receive phantom completion webhook and queue enrichment.\n\nQuery param `?token=<secret>` is the authentication mechanism since\nPhantomBuster webhooks don't support auth headers.","operationId":"handle_phantom_webhook_api_phantombuster_webhook_post","parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string","default":"","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cal/webhook":{"post":{"tags":["Cal.com Webhook"],"summary":"Cal Webhook","description":"Receive a Cal.com booking event, dispatch a branded email.","operationId":"cal_webhook_api_cal_webhook_post","parameters":[{"name":"X-Cal-Signature-256","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Cal-Signature-256"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Cal Webhook Api Cal Webhook Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cal/booking/{booking_uid}/held":{"post":{"tags":["Cal.com Webhook"],"summary":"Mark Booking Held","description":"Mark a discovery call as actually held (vs just scheduled).\n\nTrack B Workflow #1: dashboard \"Mark held\" button on lead detail.\nMatches the lead by `booking_uid` (the cal.com booking identifier,\npersisted on the lead row in _upsert_lead_from_booking via ts09).\nSets `leads.booking_held_at = NOW()` and flips the legacy\n`discovery_held` boolean for back-compat with existing queries.\n\nReturns the updated lead_id + booking_held_at timestamp.","operationId":"mark_booking_held_api_cal_booking__booking_uid__held_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"booking_uid","in":"path","required":true,"schema":{"type":"string","title":"Booking Uid"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Mark Booking Held Api Cal Booking  Booking Uid  Held Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sequencer/webhook":{"post":{"tags":["Sequencer Webhook"],"summary":"Sequencer Webhook","description":"Receive a sequencer event, persist + maybe ping Roberto.","operationId":"sequencer_webhook_api_sequencer_webhook_post","parameters":[{"name":"X-Instantly-Secret","in":"header","required":false,"schema":{"type":"string","default":"","title":"X-Instantly-Secret"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Sequencer Webhook Api Sequencer Webhook Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/fathom/webhook":{"post":{"tags":["Fathom Webhook"],"summary":"Fathom Webhook","operationId":"fathom_webhook_api_fathom_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Fathom Webhook Api Fathom Webhook Post"}}}}}}},"/api/fathom/meetings":{"get":{"tags":["Fathom Webhook"],"summary":"List Meetings","operationId":"list_meetings_api_fathom_meetings_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Lead Id"}},{"name":"company_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Company Id"}},{"name":"provider","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Provider"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response List Meetings Api Fathom Meetings Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/fathom/meetings/{meeting_id}":{"get":{"tags":["Fathom Webhook"],"summary":"Get Meeting","operationId":"get_meeting_api_fathom_meetings__meeting_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"meeting_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Meeting Id"}},{"name":"include_transcript","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Transcript"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Meeting Api Fathom Meetings  Meeting Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/fathom/meetings/{meeting_id}/re-extract":{"post":{"tags":["Fathom Webhook"],"summary":"Re Extract","description":"Re-run Claude extraction from the stored transcript (newer prompt, or a prior failure).","operationId":"re_extract_api_fathom_meetings__meeting_id__re_extract_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"meeting_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Meeting Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Re Extract Api Fathom Meetings  Meeting Id  Re Extract Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/meetings/ingest":{"post":{"tags":["Meeting Ingest"],"summary":"Ingest Meeting","operationId":"ingest_meeting_api_meetings_ingest_post","responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Ingest Meeting Api Meetings Ingest Post"}}}}}}},"/api/sales/leads/{lead_id}/enrich":{"post":{"tags":["Lead Enrichment"],"summary":"Enrich Lead","description":"Trigger enrichment for one lead. Idempotent — returns cached result if\nalready enriched (use /regenerate to force re-run).","operationId":"enrich_lead_api_sales_leads__lead_id__enrich_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","title":"Lead Id"}},{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Dry Run"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichLeadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/leads/enrich-batch":{"post":{"tags":["Lead Enrichment"],"summary":"Enrich Batch","description":"Run one tick of the enrichment queue. Respects kill switch + budget.","operationId":"enrich_batch_api_sales_leads_enrich_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichBatchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichBatchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/leads/{lead_id}/enrichment":{"get":{"tags":["Lead Enrichment"],"summary":"Get Enrichment","description":"Read the full enrichment state for a lead (for dashboard + debug).","operationId":"get_enrichment_api_sales_leads__lead_id__enrichment_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","title":"Lead Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichmentStateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/enrichment/provider-health":{"get":{"tags":["Lead Enrichment"],"summary":"Enrichment Provider Health","description":"Aggregate per-provider health from lead_enrichment_events.\n\nRoberto's daily diagnostic: which providers are healthy, slow, failing,\nor bleeding credits? Use before adding provider budget or diagnosing\na drop in ready_to_send rate.","operationId":"enrichment_provider_health_api_sales_enrichment_provider_health_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"window_days","in":"query","required":false,"schema":{"type":"integer","default":7,"title":"Window Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderHealthResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/leads/{lead_id}/enrichment/regenerate":{"post":{"tags":["Lead Enrichment"],"summary":"Regenerate Enrichment","description":"Force re-run of enrichment (bypass idempotency cache). Use after\nprompt version bump or when we want to try new signals.","operationId":"regenerate_enrichment_api_sales_leads__lead_id__enrichment_regenerate_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","title":"Lead Id"}},{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Dry Run"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EnrichLeadResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/webhooks/resend":{"post":{"tags":["Webhooks"],"summary":"Resend Webhook","description":"Resend webhook receiver. See module docstring for status code policy.","operationId":"resend_webhook_api_webhooks_resend_post","parameters":[{"name":"svix-id","in":"header","required":true,"schema":{"type":"string","title":"Svix-Id"}},{"name":"svix-timestamp","in":"header","required":true,"schema":{"type":"string","title":"Svix-Timestamp"}},{"name":"svix-signature","in":"header","required":true,"schema":{"type":"string","title":"Svix-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/check-cookies":{"post":{"tags":["Internal Cron"],"summary":"Trigger Cookie Health Check","description":"Manually trigger the cookie health check job.","operationId":"trigger_cookie_health_check_api_internal_cron_check_cookies_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/smoke-shortlist-token":{"post":{"tags":["Internal Cron"],"summary":"Mint Smoke Shortlist Token","description":"Mint a fresh shortlist magic-link token for the pinned smoke lead.\n\nUsed by the weekly prod-smoke workflow (.github/workflows/prod-smoke.yml):\nshortlist tokens expire after 14 days, so the suite mints one per run\ninstead of pinning a token that goes stale.\n\nSMOKE_SHORTLIST_LEAD_ID must point at a DEDICATED smoke-fixture lead —\nissue_token revokes the lead's prior active token, so pointing this at a\nreal lead would kill the link that lead received by email.","operationId":"mint_smoke_shortlist_token_api_internal_cron_smoke_shortlist_token_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/intro-sla-tick":{"post":{"tags":["Internal Cron"],"summary":"Intro Sla Tick","description":"Sweep overdue intro requests and re-ping Slack (Epic 1.1 SLA).\n\nEscalates every intro_requests row that is past sla_due_at, not yet\nescalated/resolved, and whose lead is still parked in deal_stage\n'intro_requested' (any stage move = Roberto engaged = clock stopped;\nthose rows are resolved instead of escalated).\n\nRuns via the external GitHub Actions cron (intro-sla-cron.yml) — NOT\nin-process APScheduler, which starves on ephemeral Railway replicas\n(enrollment incident 2026-08-18). Idempotent: escalated_at is the\ndedupe, stamped in the same transaction as the sweep.","operationId":"intro_sla_tick_api_internal_cron_intro_sla_tick_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/shortlist-refresh-tick":{"post":{"tags":["Internal Cron"],"summary":"Shortlist Refresh Tick","description":"Rebuild shortlists that got thumbed down, and say so (Epic 5.4).\n\nFor each lead whose card feedback is newer than their last refresh:\ndrop the rejected cards, keep the liked ones, pull replacements\nthrough ``list_matching_bench`` with whatever seniority shift the\nreason chips authorise, and email \"we reworked your shortlist\".\n\n**The email only goes out when cards actually changed.** A refresh\nthat swaps nothing sends nothing — \"we refreshed your shortlist\" over\nan identical slate is the fabricated-progress cousin of a countdown\ntimer, and this wave bans those.\n\nIdempotent: ``leads.shortlist_refreshed_at`` is the watermark and is\nstamped on every path that examined the feedback, including the\nno-ops, so a re-run finds nothing to redo and never re-emails.\n\nExternal GitHub Actions cron (shortlist-lifecycle-cron.yml), NOT\nin-process APScheduler — interval jobs starve on ephemeral Railway\nreplicas (enrollment incident 2026-08-18).","operationId":"shortlist_refresh_tick_api_internal_cron_shortlist_refresh_tick_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/shortlist-urgency-tick":{"post":{"tags":["Internal Cron"],"summary":"Shortlist Urgency Tick","description":"Two TRUE urgency signals the system already knew (Epic 5.5).\n\n1. **Availability change.** An engineer on a live, already-viewed\n   shortlist moved from an available state to a departed one. The\n   comparison is against the status SNAPSHOTTED when the card was\n   published, so the email is about an observed transition, never\n   about a state we merely noticed for the first time.\n2. **Expiry renewal.** A parent token dies within three days. Day 11\n   of 14: trivially true, and the buyer can verify it on day 15.\n\n**The wave doc bans fabricated scarcity.** Nothing here counts down,\ninvents viewers, or names a competing offer. If neither condition\nholds, the tick sends nothing, which is the common case.\n\nIdempotent: both notices stamp their dedupe column BEFORE the send, so\na Resend outage costs one email instead of causing a re-send storm.\n\nExternal GitHub Actions cron (shortlist-lifecycle-cron.yml), NOT\nin-process APScheduler — interval jobs starve on ephemeral Railway\nreplicas (enrollment incident 2026-08-18).","operationId":"shortlist_urgency_tick_api_internal_cron_shortlist_urgency_tick_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/speed-receipt-tick":{"post":{"tags":["Internal Cron"],"summary":"Speed Receipt Tick","description":"Recompute the median time to shortlist (Epic 5.7).\n\nThe ONLY writer of the stat www reads. Computing nightly rather than\nper request is what stops a published number moving between the page a\nbuyer reads and the email they forward five minutes later.\n\nReturning ``eligible: false`` is a normal outcome — small sample, or a\nmonth that did not beat the 72-hour promise. Every surface falls back\nto the plain guarantee copy, which is true regardless.","operationId":"speed_receipt_tick_api_internal_cron_speed_receipt_tick_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/candidate-hygiene":{"post":{"tags":["Internal Cron"],"summary":"Candidate Hygiene Tick","description":"Candidate hygiene sweep (Wave 2 Epic 2.5).\n\nRule 1: 90-day idle Applied/Screening/Bench → Inactive. Rule 2: Applied\nwhose latest evaluation expired ≥30 days ago with nothing active and no\nre-application → Inactive. Each transition records a\n`{type: 'auto_inactive', reason}` note; re-application (forms.py) and\ncandidate_hygiene_service.reactivate() reverse it.\n\nCalled by .github/workflows/bench-freshness-cron.yml (daily 09:00 UTC,\nafter bench-staleness and in-pool-ping); idempotent and advisory-locked,\nso a manual re-run is always safe.","operationId":"candidate_hygiene_tick_api_internal_cron_candidate_hygiene_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/bench-staleness":{"post":{"tags":["Internal Cron"],"summary":"Bench Staleness Tick","description":"Bench freshness sweep (Wave 2 Epic 2.3).\n\nVetted candidates whose availability_confirmed_at is older than\nBENCH_STALE_AFTER_DAYS get a 30-second check-in nudge; after\nBENCH_STALE_MAX_PINGS unanswered nudges the row is marked 'stale' and\nleaves every shortlist surface until the candidate saves availability.\nNo-ops with {\"skipped\": \"flag\"} while BENCH_STALENESS_ENABLED is off.\nAdvisory-locked; a re-run never double-sends. Runs FIRST in the daily\nworkflow so a candidate due for both heartbeats gets one email.","operationId":"bench_staleness_tick_api_internal_cron_bench_staleness_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/referral-reward-tick":{"post":{"tags":["Internal Cron"],"summary":"Referral Reward Tick","description":"Referral reward APPROVALS (#98). Never pays anything.\n\n* Engineer referrals: Pending → Approved once the placement is Active,\n  past the day-60 gate (30 for grandfathered rows) and its first\n  invoice is paid.\n* Client referrals (v2, $5,000): creates the two tranches as Pending and\n  approves each when earned ($2,500 first invoice paid; $2,500 day 90\n  active with 3 invoices paid).\n\nPayout stays manual while Stripe is frozen. Advisory-locked and every\nwrite is conditional, so a re-run approves nothing twice. Called daily\nby .github/workflows/bench-freshness-cron.yml.","operationId":"referral_reward_tick_api_internal_cron_referral_reward_tick_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/in-pool-ping":{"post":{"tags":["Internal Cron"],"summary":"In Pool Ping Tick","description":"14-day \"still in the pool\" heartbeat (candidate_status_ping_service).\n\nMoved off APScheduler in Wave 2 Epic 2.3 (it double-fired across uvicorn\nworkers). Advisory-locked; per-row last_status_ping_at makes re-runs\nidempotent inside the 14-day window.","operationId":"in_pool_ping_tick_api_internal_cron_in_pool_ping_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/daily-digest":{"post":{"tags":["Internal Cron"],"summary":"Trigger Daily Digest","description":"Manually trigger the daily outbound digest to Slack.","operationId":"trigger_daily_digest_api_internal_cron_daily_digest_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/checkin-reminder-tick":{"post":{"tags":["Internal Cron"],"summary":"Checkin Reminder Tick","description":"Weekly check-in sweep — nudges the ENGINEER, digests the founder.\n\nR2 Wave 4 Epic 4.2. Moved off in-process APScheduler (it was a\nMonday 09:00 CronTrigger with no lock, so it fired once per uvicorn\nworker and starved whenever a Railway replica restarted over the\nweekend — the 2026-08-18 enrollment failure mode). Driven by\n.github/workflows/checkin-reminder-cron.yml.\n\nIdempotent: a candidate who already received the reminder inside\nREMINDER_DEDUPE_DAYS is skipped, so a hand re-run after a failed cron\nrun is safe.","operationId":"checkin_reminder_tick_api_internal_cron_checkin_reminder_tick_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/placement-continuity-tick":{"post":{"tags":["Internal Cron"],"summary":"Placement Continuity Tick","description":"Vetting Integrity v1 check N: day-1 client \"same person?\" emails and\nthe one day-3 reminder (placement_continuity_service.run_tick).\n\nDriven by the cron-scheduler opt-in job ``placement_continuity`` (daily).\nNo-ops with {\"skipped\": \"flag\"} while PLACEMENT_CONTINUITY_ENABLED is\noff. Advisory-locked; send markers live in integrity_signals, so a\nre-run never double-sends.","operationId":"placement_continuity_tick_api_internal_cron_placement_continuity_tick_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/vetting-invite-tick":{"post":{"tags":["Internal Cron"],"summary":"Vetting Invite Tick","description":"PR #528 (VETTING_SEND_INVITE_ENABLED): retry a first invite that\nfailed (within 24 hours of the request), send the ONE 48-hour reminder,\nthen delete invite addresses 30 days after their request ended.\n\nExternal cron (.github/workflows/grading-retry-cron.yml, hourly), never\nthe in-process scheduler: interval jobs starve on Railway replicas (the\nenrollment stall, 2026-08-18; PR #528 e2e W5). Idempotent: every send is\nclaimed by a conditional UPDATE in the send's own transaction, so a\ndouble call sends nothing twice. The sends are flag-gated; the purge\nruns whatever the flags say.","operationId":"vetting_invite_tick_api_internal_cron_vetting_invite_tick_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/integrity-retention":{"post":{"tags":["Internal Cron"],"summary":"Integrity Retention Tick","description":"Vetting Integrity v1 (PR5): purge raw IP + device hash older than 90\ndays from integrity_request_meta. Coarse evidence (country, ASN, hosting\nand VPN booleans, browser zone) stays so existing D signals remain\nexplainable.\n\nRuns whatever INTEGRITY_SIGNALS_ENABLED says: data captured while the\nflag was on must still age out after it is turned off. Idempotent (a\nsecond run touches nothing). Driven daily by\n.github/workflows/bench-freshness-cron.yml — external cron, never the\nin-process scheduler.","operationId":"integrity_retention_tick_api_internal_cron_integrity_retention_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/cron/vetting-delivery-tick":{"post":{"tags":["Internal Cron"],"summary":"Vetting Delivery Tick","description":"PR #524 round 6: deliver ready vetting reports, send the 48h\nfollow-ups, and run the two retention purges (third-party media 90 days\nafter delivery; work a requester discarded, 90 days after the discard).\n\nExternal cron (.github/workflows/grading-retry-cron.yml, hourly), never\nthe in-process scheduler alone: interval jobs starve on Railway replicas\n(the enrollment stall, 2026-08-18). The lifecycle tick keeps calling the\nsame code as a fallback; both take one advisory lock and every step is\nidempotent (conditional-UPDATE claims, purges match only rows that still\nhold content), so a double call delivers, follows up and purges nothing\ntwice. Delivery is gated on VETTING_ENABLED; the purges run whatever the\nflag says.","operationId":"vetting_delivery_tick_api_internal_cron_vetting_delivery_tick_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/flags":{"get":{"tags":["Internal Cron"],"summary":"Effective Flags","description":"Effective funnel flag states + registered scheduler jobs (cron-token guarded).\n\n`scheduler_jobs` reflects whichever uvicorn worker answered this request\n(each worker runs its own APScheduler). Every worker registers the same\njob list from the same env, so this is all-or-nothing detection — it\ncatches OUTREACH_ENABLED=false (no jobs anywhere), not a single worker\nwhose scheduler died. `pid` tells repeated calls apart.","operationId":"effective_flags_api_internal_flags_get","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/my-leads":{"get":{"tags":["Sales"],"summary":"Get My Leads","description":"Get leads assigned to the current user (or all if founder with ?rep_id=).","operationId":"get_my_leads_api_sales_my_leads_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/my-pipeline":{"get":{"tags":["Sales"],"summary":"Get My Pipeline","description":"Get current user's leads grouped by deal_stage.","operationId":"get_my_pipeline_api_sales_my_pipeline_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/my-stats":{"get":{"tags":["Sales"],"summary":"Get My Stats","description":"Get aggregated performance stats for current user.","operationId":"get_my_stats_api_sales_my_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepStatsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/my-commission":{"get":{"tags":["Sales"],"summary":"Get My Commission","description":"Get commission calculation for current user in a given period.","operationId":"get_my_commission_api_sales_my_commission_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"year","in":"query","required":false,"schema":{"type":"integer","title":"Year"}},{"name":"month","in":"query","required":false,"schema":{"type":"integer","maximum":12,"minimum":1,"title":"Month"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommissionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/leads/{lead_id}/stage":{"patch":{"tags":["Sales"],"summary":"Update Lead Stage","description":"Update a lead's deal stage. Auto-logs activity.","operationId":"update_lead_stage_api_sales_leads__lead_id__stage_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","title":"Lead Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DealStageUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/leads/{lead_id}/activities":{"get":{"tags":["Sales"],"summary":"Get Lead Activities","description":"Get all activities for a specific lead, newest first.","operationId":"get_lead_activities_api_sales_leads__lead_id__activities_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","title":"Lead Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/log-activity":{"post":{"tags":["Sales"],"summary":"Log Activity","description":"Log a sales activity (call, email, meeting, note).","operationId":"log_activity_api_sales_log_activity_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SalesActivityCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/import-leads":{"post":{"tags":["Sales"],"summary":"Import Leads","description":"Bulk import leads from CSV/PhantomBuster. Dedup by email.","operationId":"import_leads_api_sales_import_leads_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadImportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadImportResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/import-csv":{"post":{"tags":["Sales"],"summary":"Import Leads Csv","description":"Bulk import leads from CSV file (PhantomBuster export). Dedup by email.","operationId":"import_leads_csv_api_sales_import_csv_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"source","in":"query","required":false,"schema":{"type":"string","default":"PhantomBuster","title":"Source"}},{"name":"auto_assign","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Auto Assign"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_import_leads_csv_api_sales_import_csv_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/assign-lead":{"post":{"tags":["Sales"],"summary":"Assign Lead","description":"Assign a lead to a sales rep. Founder only.","operationId":"assign_lead_api_sales_assign_lead_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadAssignRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/leaderboard":{"get":{"tags":["Sales"],"summary":"Get Leaderboard","description":"All sales reps ranked by performance. Founder only.","operationId":"get_leaderboard_api_sales_leaderboard_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/rep/{rep_id}/stats":{"get":{"tags":["Sales"],"summary":"Get Rep Stats","description":"Get detailed stats for a specific rep. Founder only.","operationId":"get_rep_stats_api_sales_rep__rep_id__stats_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"rep_id","in":"path","required":true,"schema":{"type":"string","title":"Rep Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RepStatsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/known-explorium-ids":{"get":{"tags":["Sales"],"summary":"Get Known Explorium Ids","description":"Get all known Explorium IDs for credit protection.\n\nCall this before every VP search to build the exclude list,\npreventing credits from being spent on already-known companies.","operationId":"get_known_explorium_ids_api_sales_known_explorium_ids_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnownExploriumIdsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/import-vibe-prospecting":{"post":{"tags":["Sales"],"summary":"Import Vibe Prospecting","description":"Import enriched leads from Vibe Prospecting (JSON). 3-layer dedup.\n\nv2.4: now passes signal_source / activation_channel / signal_metadata\nthrough to the import service for attribution preservation. See ADR-001.\nLegacy callers omitting these fields fall back to derive-from-source.","operationId":"import_vibe_prospecting_api_sales_import_vibe_prospecting_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VibeProspectingImportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VibeProspectingImportResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/import-outbound-batch":{"post":{"tags":["Sales"],"summary":"Import Outbound Batch","description":"Unified outbound-lead import endpoint — ADR-002.\n\nMirrors /import-vibe-prospecting but is the canonical entry point for ALL\noutbound signal sources (Bombora, TheirStack, PhantomBuster Sales Nav,\nreferrals, manual). The `signal_source` field in the request body is the\nsource of truth for attribution; `source` is kept for backward compat.\n\nRecommended payload shape:\n    {\n      \"leads\": [...],\n      \"source\": \"TheirStack\",                  # human-readable\n      \"signal_source\": \"theirstack\",           # enum for attribution\n      \"activation_channel\": \"multi_channel\",   # how we'll reach them\n      \"signal_metadata\": {                     # source-specific payload\n        \"open_roles\": [...],\n        \"posted_dates\": [...],\n        \"tech_stack\": [...]\n      },\n      \"auto_assign\": true\n    }","operationId":"import_outbound_batch_api_sales_import_outbound_batch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VibeProspectingImportRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VibeProspectingImportResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/import-vibe-prospecting-csv":{"post":{"tags":["Sales"],"summary":"Import Vibe Prospecting Csv","description":"Import enriched leads from Vibe Prospecting CSV file. 3-layer dedup.\n\nThe `source` param tracks the ORIGINAL source of the contact data (where it was\ndiscovered). `enrichment_source` is set separately to 'vibe_prospecting' since\nthis endpoint always uses VP for enrichment.\n\nv2.4 ATTRIBUTION FIX (ADR-001): when this endpoint is called by the\nphantombuster_webhook agentic flow to enrich PB-scraped leads, pass\n`signal_source=phantombuster_search` so the attribution survives the\nenrichment cycle. Previously the import always stamped 'VibeProspecting'\nover the PB origin, destroying attribution.","operationId":"import_vibe_prospecting_csv_api_sales_import_vibe_prospecting_csv_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"auto_assign","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Auto Assign"}},{"name":"source","in":"query","required":false,"schema":{"type":"string","description":"Origin of the lead contact data. Use 'PhantomBuster' for Sales Nav scrapes enriched by VP, or 'VibeProspecting' for VP-discovered leads.","default":"VibeProspecting","title":"Source"},"description":"Origin of the lead contact data. Use 'PhantomBuster' for Sales Nav scrapes enriched by VP, or 'VibeProspecting' for VP-discovered leads."},{"name":"signal_source","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"v2.4 Track A — attribution stamp that survives enrichment. Use 'phantombuster_search' when PB-scrape webhook calls this endpoint to enrich PB leads (prevents the source-overwrite bug — see ADR-001). If omitted, derived from `source` for backward compat.","title":"Signal Source"},"description":"v2.4 Track A — attribution stamp that survives enrichment. Use 'phantombuster_search' when PB-scrape webhook calls this endpoint to enrich PB leads (prevents the source-overwrite bug — see ADR-001). If omitted, derived from `source` for backward compat."},{"name":"activation_channel","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Activation Channel"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_import_vibe_prospecting_csv_api_sales_import_vibe_prospecting_csv_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VibeProspectingImportResult"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/leads/{lead_id}/demo-completed":{"post":{"tags":["Sales"],"summary":"Mark Demo Completed","description":"Track B Workflow #2 — log that a demo was completed.\n\nSets `leads.demo_completed_at = NOW()`. Idempotent: subsequent calls\noverwrite (rare — used if Roberto logs the wrong demo and needs to\ncorrect). Returns the updated demo_completed_at timestamp.","operationId":"mark_demo_completed_api_sales_leads__lead_id__demo_completed_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","title":"Lead Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/DemoCompletedRequest"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/leads/{lead_id}/close":{"post":{"tags":["Sales"],"summary":"Close Deal","description":"Track B Workflow #3 — close a deal (won or lost).\n\nOn close-won: sets `closed_at = NOW()`, optionally `deal_value`,\n`closed_lost_reason = NULL`, and moves `deal_stage = 'closedwon'`.\n\nOn close-lost: sets `closed_at = NOW()`, `closed_lost_reason`\n(REQUIRED — enum from ALLOWED_LOSS_REASONS), and moves\n`deal_stage = 'closedlost'`. The mandatory loss reason is the CSO's\nmonthly histogram — see SALES_PIPELINE_STAGES.md.\n\nSide effects: unenrolls the lead from any active nurture sequence\n(we stop sending if they bought OR if they're gone).","operationId":"close_deal_api_sales_leads__lead_id__close_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","title":"Lead Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DealCloseRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/leads/{lead_id}/convert":{"post":{"tags":["Sales"],"summary":"Convert Lead To Company","description":"Convert a lead into a client company — the moment the deal verbally\ncloses (Epic 1.2).\n\nReuses the existing POST /api/companies creation chain verbatim (all\n7 onboarding steps fire: Stripe, portal user, MSA via BoldSign, Slack\nchannel, credentials email, first project). On top of it:\n\n  1. Links company.lead_id (channel attribution).\n  2. Closes the lead as won (same semantics as /close).\n  3. Resolves any open intro-request SLA timers.\n\nHard guards (the whole point of the button): refuses to run without a\nsigner, without a BoldSign key, or into an existing domain — and\nreports `msa_sent` honestly so a BoldSign API failure is a red error\nin the dialog, not a log line.","operationId":"convert_lead_to_company_api_sales_leads__lead_id__convert_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","title":"Lead Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadConvertRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/admin/source-cost":{"post":{"tags":["Sales"],"summary":"Upsert Source Cost","description":"Track B Workflow #6 — admin endpoint to enter monthly costs per source.\n\nUsed by the admin UI to log Explorium/TheirStack/PhantomBuster/Sales Nav/\nInstantly subscription + credit costs each month. Powers the \"Cost per\nlead by source\" dashboard tile.\n\nUPSERT on (month, signal_source). If a row exists, update it (corrections\nare common in month-1 entries).","operationId":"upsert_source_cost_api_sales_admin_source_cost_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourceCostRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Sales"],"summary":"List Source Costs","description":"List monthly source costs. Filter by ?month=YYYY-MM.","operationId":"list_source_costs_api_sales_admin_source_cost_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"month","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Month"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/feature-flags/outbound_auto_send_enabled":{"get":{"tags":["Sales"],"summary":"Get Outbound Auto Send Enabled","description":"Read the global outbound-send kill switch state.\n\nDefault 'false' (set in ts11 migration) — new imports land as\n'pending_activation' until Roberto explicitly enables auto-send.","operationId":"get_outbound_auto_send_enabled_api_sales_feature_flags_outbound_auto_send_enabled_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Sales"],"summary":"Set Outbound Auto Send Enabled","description":"Flip the global outbound-send kill switch (founder + internal_admin).\n\nAffects FUTURE imports only — existing pending leads stay pending until\nexplicitly activated via POST /leads/activate. This is intentional:\nflipping the global flag should NOT be a one-click trapdoor that\ndrains 200 queued leads into Instantly at once.","operationId":"set_outbound_auto_send_enabled_api_sales_feature_flags_outbound_auto_send_enabled_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutboundAutoSendToggleRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/leads/pending-activation":{"get":{"tags":["Sales"],"summary":"List Pending Activation Leads","description":"List leads currently held at auto_send_status='pending_activation'.\n\nSurfaces the queue Roberto reviews on the dashboard before clicking\n\"Activate\". Ordered newest-first so the freshest imports land at the\ntop. Excludes leads already activated, sent, or paused.\n\nRestricted to founder + internal_admin: only admins can see the\ncross-rep view (and only admins can act on it via POST /activate).\nSales reps see the OFF/count via the banner without needing the rows.","operationId":"list_pending_activation_leads_api_sales_leads_pending_activation_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/leads/activate":{"post":{"tags":["Sales"],"summary":"Activate Leads","description":"Flip selected leads from 'pending_activation' to 'ready_to_send'.\n\nOnly leads currently at 'pending_activation' are touched — already-\nactivated, sent, or paused leads are silently skipped (idempotent).\nRestricted to founder + internal_admin: this is the gate that opens\nreal outbound sends, same blast-radius class as the global flag flip.\n\nReturns count of leads actually activated (may be < lead_ids if some\nwere already past pending_activation).","operationId":"activate_leads_api_sales_leads_activate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ActivateLeadsRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/leads/{lead_id}/linkedin-accepted":{"post":{"tags":["Sales"],"summary":"Mark Linkedin Accepted","description":"Record a REAL LinkedIn connection accept + arm the nurture spine.\n\nLinkedIn accepts are not programmatically detectable (sequence_engine's\nconnect_accepted_at is a time-elapsed assumption). The Chrome-sweep\nskills (/re-touch-due, /linkedin-mcp-outreach) call this when they SEE\nan accept in the connections list. Effects:\n\n  1. leads.linkedin_accepted_at = NOW() (idempotent — first call wins)\n  2. If the lead has no nurture sequence, enroll in `re_engagement`\n     with a 7-day fuse — same safety-net rule as the reply webhook:\n     the human DM owns the first week; the machine catches a stall.\n\nFix #1 (handoff spine), LinkedIn arm.","operationId":"mark_linkedin_accepted_api_sales_leads__lead_id__linkedin_accepted_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/feature-flags/weekly_injection_target":{"get":{"tags":["Sales"],"summary":"Get Weekly Injection Target","description":"Read the current weekly_injection_target from feature_flags.\n\nUsed by /vibe-prospecting skill to cap fetch quantity at the per-week\ncap (Workflow #8). Returns numeric string (e.g., \"20\") or default 20 if\nunset. See implementation doc §5.5 for the warmup schedule.","operationId":"get_weekly_injection_target_api_sales_feature_flags_weekly_injection_target_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/sales/slack-pings/{ping_id}/respond":{"post":{"tags":["Sales"],"summary":"Mark Slack Ping Responded","description":"Track B Workflow #5 — manually mark a slack_pings row as answered.\n\nUsed when Roberto responds to a #sales-signals ping but can't (or\ndidn't) react with an emoji. Sets responded_at = NOW() and\nresponse_type = 'manual'.\n\nThe auto-update path via Slack reactions is a follow-up — needs a\nSlack app event subscription (reactions:read scope) that Roberto\nconfigures. See implementation doc §3.1 Workflow #5.","operationId":"mark_slack_ping_responded_api_sales_slack_pings__ping_id__respond_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"ping_id","in":"path","required":true,"schema":{"type":"string","title":"Ping Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/slack-pings/pending":{"get":{"tags":["Sales"],"summary":"List Pending Slack Pings","description":"List slack_pings with no response that are older than X hours.\n\nPowers the \"Reply SLA breach\" alert + the dashboard SLA% computation.\nDefault: ≥1h old = SLA breach (per implementation doc §10.1).","operationId":"list_pending_slack_pings_api_sales_slack_pings_pending_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"older_than_hours","in":"query","required":false,"schema":{"type":"integer","maximum":72,"minimum":1,"default":1,"title":"Older Than Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/leads/{lead_id}/mark-held":{"post":{"tags":["Sales"],"summary":"Mark Lead Discovery Held","description":"Mark a discovery call as actually held — keyed by lead_id, not booking_uid.\n\nTrack B Workflow #1 — UI version of POST /api/cal/booking/{uid}/held.\n\nThe dashboard already knows the lead_id (it's the row the user is acting\non), so calling by lead_id is friction-free. The booking-uid endpoint\nremains available for flows that only know the cal.com uid (Slack\nreaction handlers reading from the booking link, etc.).\n\nIdempotent: subsequent calls are no-ops (booking_held_at stays at the\nfirst-mark value). Returns 404 if the lead has no booking_scheduled_at.","operationId":"mark_lead_discovery_held_api_sales_leads__lead_id__mark_held_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","title":"Lead Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sales/theirstack-search":{"post":{"tags":["Sales"],"summary":"Theirstack Search","description":"v2.4 Track A — discover companies actively hiring via TheirStack.\n\nThin wrapper around theirstack_service.search_companies_hiring that the\n`/vibe-prospecting --signal=theirstack` skill calls. Returns the\ncompany list + credit cost; the skill then runs Explorium match-business\n+ match-prospects + enrich-prospects on each to fill in emails and\nimport via /api/sales/import-outbound-batch.\n\nCaller responsibilities (the skill):\n  1. Read weekly_injection_target via /api/sales/feature-flags/...\n  2. Cap `limit` at remaining_budget_this_week\n  3. After this call returns, enrich each company via vpai\n  4. POST enriched leads to /api/sales/import-outbound-batch with\n     signal_source='theirstack' and signal_metadata containing the\n     open_roles/posted_dates returned here\n\nRaw response is also persisted to disk by the service (per the VP\ncredit-burn lesson — never inspect API responses without persisting).","operationId":"theirstack_search_api_sales_theirstack_search_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TheirStackSearchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/phantombuster/launch":{"post":{"tags":["PhantomBuster"],"summary":"Launch Phantom","description":"Launch a PhantomBuster phantom job.","operationId":"launch_phantom_api_phantombuster_launch_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LaunchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/phantombuster/jobs":{"get":{"tags":["PhantomBuster"],"summary":"List Jobs","description":"List PhantomBuster sourcing jobs.","operationId":"list_jobs_api_phantombuster_jobs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status_filter","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status Filter"}},{"name":"job_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/phantombuster/jobs/{job_id}":{"get":{"tags":["PhantomBuster"],"summary":"Get Job","description":"Get a single sourcing job's status and results.","operationId":"get_job_api_phantombuster_jobs__job_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["PhantomBuster"],"summary":"Cancel Job","description":"Cancel a running PhantomBuster job.","operationId":"cancel_job_api_phantombuster_jobs__job_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/phantombuster/jobs/{job_id}/import":{"post":{"tags":["PhantomBuster"],"summary":"Manual Import","description":"Manually trigger import for a completed job.","operationId":"manual_import_api_phantombuster_jobs__job_id__import_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/phantombuster/jobs/{job_id}/poll":{"post":{"tags":["PhantomBuster"],"summary":"Force Poll","description":"Force-poll PhantomBuster for job status update.","operationId":"force_poll_api_phantombuster_jobs__job_id__poll_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/phantombuster/phantoms":{"get":{"tags":["PhantomBuster"],"summary":"List Phantoms","description":"List available phantom types and their configured agent IDs.","operationId":"list_phantoms_api_phantombuster_phantoms_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/campaigns":{"post":{"tags":["Campaigns"],"summary":"Create Campaign","operationId":"create_campaign_api_campaigns_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCampaignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Campaigns"],"summary":"List Campaigns","operationId":"list_campaigns_api_campaigns_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"campaign_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/campaigns/{campaign_id}":{"get":{"tags":["Campaigns"],"summary":"Get Campaign","operationId":"get_campaign_api_campaigns__campaign_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Campaigns"],"summary":"Update Campaign","operationId":"update_campaign_api_campaigns__campaign_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","title":"Campaign Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateCampaignRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/campaigns/{campaign_id}/activate":{"post":{"tags":["Campaigns"],"summary":"Activate Campaign","operationId":"activate_campaign_api_campaigns__campaign_id__activate_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/campaigns/{campaign_id}/pause":{"post":{"tags":["Campaigns"],"summary":"Pause Campaign","operationId":"pause_campaign_api_campaigns__campaign_id__pause_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/campaigns/{campaign_id}/funnel":{"get":{"tags":["Campaigns"],"summary":"Get Campaign Funnel","operationId":"get_campaign_funnel_api_campaigns__campaign_id__funnel_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/campaigns/{campaign_id}/export":{"get":{"tags":["Campaigns"],"summary":"Export Campaign","operationId":"export_campaign_api_campaigns__campaign_id__export_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"campaign_id","in":"path","required":true,"schema":{"type":"string","title":"Campaign Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/companies":{"get":{"tags":["companies"],"summary":"List Companies","description":"List all companies (founder only)\n\nSupports filtering by status, pricing tier, and search.\nServer-side pagination with total count.","operationId":"list_companies_api_companies_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"pricing_tier","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by pricing tier","title":"Pricing Tier"},"description":"Filter by pricing tier"},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by name, domain, or email","title":"Search"},"description":"Search by name, domain, or email"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":25,"title":"Per Page"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["companies"],"summary":"Create Company","description":"Create a new company (founder only)\n\nOrder: DB first (source of truth) → Stripe → side effects.\nIf Stripe fails, company still exists — retry Stripe later.","operationId":"create_company_api_companies_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/companies/{company_id}":{"get":{"tags":["companies"],"summary":"Get Company","description":"Get single company by ID\n\nFounders can access any company\nClient users can only access their own company","operationId":"get_company_api_companies__company_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["companies"],"summary":"Update Company","description":"Update company (founder or client_admin)\n\nClient admins can only update their own company","operationId":"update_company_api_companies__company_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"string","title":"Company Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["companies"],"summary":"Delete Company","description":"Archive company (founder only)\n\nSets status to \"Churned\" rather than deleting","operationId":"delete_company_api_companies__company_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"string","title":"Company Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/companies/{company_id}/placements":{"get":{"tags":["companies"],"summary":"Get Company Placements","description":"Get all placements for a company\n\nFounders can access any company\nClient users can only access their own company","operationId":"get_company_placements_api_companies__company_id__placements_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/companies/{company_id}/invoices":{"get":{"tags":["companies"],"summary":"Get Company Invoices","description":"Get all invoices for a company\n\nFounders can access any company\nClient users can only access their own company","operationId":"get_company_invoices_api_companies__company_id__invoices_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/placements":{"get":{"tags":["placements"],"summary":"List Placements","description":"List all placements\n\nFounders see all placements\nClient users see only their company's placements","operationId":"list_placements_api_placements_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"client_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by client","title":"Client Id"},"description":"Filter by client"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PlacementResponse"},"title":"Response List Placements Api Placements Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["placements"],"summary":"Create Placement","description":"Create a new placement (founder only)\n\nSets status to \"Proposed\" by default","operationId":"create_placement_api_placements_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlacementCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlacementResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/placements/pipeline":{"get":{"tags":["placements"],"summary":"Get Pipeline","description":"Get placements pipeline (founder only)\n\nReturns placements grouped by status","operationId":"get_pipeline_api_placements_pipeline_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Pipeline Api Placements Pipeline Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/placements/{placement_id}":{"get":{"tags":["placements"],"summary":"Get Placement","description":"Get single placement by ID","operationId":"get_placement_api_placements__placement_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"placement_id","in":"path","required":true,"schema":{"type":"string","title":"Placement Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlacementResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["placements"],"summary":"Update Placement","description":"Update placement (founder only)\n\nCan update status, dates, etc.","operationId":"update_placement_api_placements__placement_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"placement_id","in":"path","required":true,"schema":{"type":"string","title":"Placement Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlacementUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlacementResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["placements"],"summary":"Delete Placement","description":"Delete placement (founder only)\n\nActually just marks as Churned rather than hard delete","operationId":"delete_placement_api_placements__placement_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"placement_id","in":"path","required":true,"schema":{"type":"string","title":"Placement Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/placements/{placement_id}/churn":{"post":{"tags":["placements"],"summary":"Churn Placement","description":"Mark placement as churned (founder only)\n\nSets status to Churned and records churn reason","operationId":"churn_placement_api_placements__placement_id__churn_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"placement_id","in":"path","required":true,"schema":{"type":"string","title":"Placement Id"}},{"name":"churn_reason","in":"query","required":true,"schema":{"type":"string","title":"Churn Reason"}},{"name":"replacement_offered","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Replacement Offered"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlacementResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/nps/response":{"post":{"tags":["nps"],"summary":"Record Nps Response","description":"Record NPS survey response and trigger automated actions.\n\n**Public endpoint** - No authentication required (survey responses come\nfrom the /nps/[placement_id] page linked in survey emails).\n\n**Actions by Score:**\n- **9-10 (Promoter):** Slack celebration + referral-request task (+24h)\n- **7-8 (Passive):** Slack note + follow-up task (+3 days)\n- **0-6 (Detractor):** URGENT Slack alert + founder-call-today task\n\nRewritten for Neon (R2 Wave 1, Epic 1.4a) — the previous version wrote\nAirtable-era field names (\"NPS_Score\", \"Client\") that NeonService's\nstrict column allow-lists silently dropped, so no response was ever\nactually saved.\n\n`is_smoke=true` = prod-smoke dry-run: validates the placement, returns\nthe category, writes nothing, pings nobody.","operationId":"record_nps_response_api_nps_response_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NPSResponseCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NPSResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/nps/stats":{"get":{"tags":["nps"],"summary":"Get Nps Stats","description":"Get overall NPS statistics\n\n**Query Parameters:**\n- `days`: Number of days to analyze (default: 90)\n\n**Returns:**\n- Overall NPS score (-100 to 100)\n- Promoter/Passive/Detractor counts and percentages\n- Response rate\n- Average score\n\n**Example:**\n```\nGET /api/nps/stats?days=30\n```","operationId":"get_nps_stats_api_nps_stats_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","default":90,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NPSStats"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/nps/placements/{placement_id}":{"get":{"tags":["nps"],"summary":"Get Placement Nps History","description":"Get complete NPS history for a placement\n\nShows all NPS scores (30-day, 90-day, 180-day) and trend\n\n**Example:**\n```\nGET /api/nps/placements/recPlacement123\n```","operationId":"get_placement_nps_history_api_nps_placements__placement_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"placement_id","in":"path","required":true,"schema":{"type":"string","title":"Placement Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlacementNPSHistory"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/nps/trends":{"get":{"tags":["nps"],"summary":"Get Nps Trends","description":"Get NPS trends over time (monthly)\n\n**Query Parameters:**\n- `months`: Number of months to return (default: 6)\n\n**Returns:** Array of monthly NPS scores\n\n**Example:**\n```\nGET /api/nps/trends?months=12\n```","operationId":"get_nps_trends_api_nps_trends_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"months","in":"query","required":false,"schema":{"type":"integer","default":6,"title":"Months"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NPSTrendData"},"title":"Response Get Nps Trends Api Nps Trends Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/nps/webhooks/tally":{"post":{"tags":["nps"],"summary":"Tally Webhook","description":"Tally.so webhook handler (FREE survey platform)\n\nReceives NPS survey responses from Tally.so and processes them\n\n**Tally.so Webhook Setup:**\n```\nTally Settings → Integrations → Webhooks\nURL: https://api.ruzora.com/api/nps/webhooks/tally\nMethod: POST\nTrigger: On form submission\n```\n\n**Payload Example:**\n```json\n{\n    \"eventType\": \"FORM_RESPONSE\",\n    \"eventId\": \"xyz123\",\n    \"createdAt\": \"2026-02-20T14:30:00Z\",\n    \"data\": {\n        \"responseId\": \"abc456\",\n        \"submissionId\": \"def789\",\n        \"formId\": \"YOUR_FORM_ID\",\n        \"formName\": \"30-Day NPS Survey\",\n        \"fields\": [\n            {\n                \"key\": \"question_1\",\n                \"label\": \"On a scale of 0-10...\",\n                \"type\": \"NUMBER\",\n                \"value\": 9\n            },\n            {\n                \"key\": \"question_2\",\n                \"label\": \"What do you love most?\",\n                \"type\": \"TEXTAREA\",\n                \"value\": \"Juan is amazing!\"\n            },\n            {\n                \"key\": \"placement_id\",\n                \"type\": \"HIDDEN_FIELDS\",\n                \"value\": \"recPlacement123\"\n            },\n            {\n                \"key\": \"survey_type\",\n                \"type\": \"HIDDEN_FIELDS\",\n                \"value\": \"30_day\"\n            },\n            {\n                \"key\": \"client_email\",\n                \"type\": \"HIDDEN_FIELDS\",\n                \"value\": \"sarah@acme.com\"\n            }\n        ]\n    }\n}\n```","operationId":"tally_webhook_api_nps_webhooks_tally_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/projects/search":{"get":{"tags":["projects"],"summary":"Search Projects","description":"Search projects by title or company name. Returns open/active projects.","operationId":"search_projects_api_projects_search_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"type":"string","minLength":0,"default":"","title":"Q"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects":{"get":{"tags":["projects"],"summary":"List Projects","description":"List projects with optional filters, enriched with company name.","operationId":"list_projects_api_projects_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"company_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"assigned_recruiter_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned Recruiter Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["projects"],"summary":"Create Project","description":"Create a new project (founder only).","operationId":"create_project_api_projects_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}":{"get":{"tags":["projects"],"summary":"Get Project","description":"Get a single project by ID.","operationId":"get_project_api_projects__project_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["projects"],"summary":"Update Project","description":"Update a project.","operationId":"update_project_api_projects__project_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProjectUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["projects"],"summary":"Delete Project","description":"Soft-delete a project by setting status to Closed (founder only).","operationId":"delete_project_api_projects__project_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/pipeline":{"get":{"tags":["projects"],"summary":"Get Project Pipeline","description":"Get candidates grouped by stage for Kanban view.","operationId":"get_project_pipeline_api_projects__project_id__pipeline_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/candidates":{"get":{"tags":["projects"],"summary":"List Project Candidates","description":"List candidates for a project, enriched with candidate data.","operationId":"list_project_candidates_api_projects__project_id__candidates_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"stage","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stage"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["projects"],"summary":"Submit Candidate To Project","description":"Submit a candidate to a project.","operationId":"submit_candidate_to_project_api_projects__project_id__candidates_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitCandidateRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/candidates/{pc_id}/stage":{"patch":{"tags":["projects"],"summary":"Move Candidate Stage","description":"Move a candidate to a new pipeline stage.","operationId":"move_candidate_stage_api_projects__project_id__candidates__pc_id__stage_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"pc_id","in":"path","required":true,"schema":{"type":"string","title":"Pc Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MoveCandidateStageRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/candidates/{pc_id}/interview":{"patch":{"tags":["projects"],"summary":"Schedule Interview","description":"Schedule an interview for a project candidate.","operationId":"schedule_interview_api_projects__project_id__candidates__pc_id__interview_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"pc_id","in":"path","required":true,"schema":{"type":"string","title":"Pc Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScheduleInterviewRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/match-candidates":{"get":{"tags":["projects"],"summary":"Match Candidates","description":"Score and rank candidates for a project.","operationId":"match_candidates_api_projects__project_id__match_candidates_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/documents":{"get":{"tags":["documents"],"summary":"List Documents","operationId":"list_documents_api_documents_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"entity_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Type"}},{"name":"entity_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Entity Id"}},{"name":"doc_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doc Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["documents"],"summary":"Create Document","operationId":"create_document_api_documents_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/documents/{doc_id}":{"get":{"tags":["documents"],"summary":"Get Document","operationId":"get_document_api_documents__doc_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","title":"Doc Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["documents"],"summary":"Update Document","operationId":"update_document_api_documents__doc_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","title":"Doc Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocumentUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["documents"],"summary":"Delete Document","operationId":"delete_document_api_documents__doc_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","title":"Doc Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/documents/{doc_id}/download":{"get":{"tags":["documents"],"summary":"Download Document","description":"Generate a temporary presigned URL for downloading a document.\n\nDocuments are stored privately in R2; recruiters need a temp URL to\nactually open the file. URL expires after 1 hour to limit PII exposure\nif the link is shared.","operationId":"download_document_api_documents__doc_id__download_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"doc_id","in":"path","required":true,"schema":{"type":"string","title":"Doc Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/engagement/at-risk":{"get":{"tags":["engagement"],"summary":"Get At Risk Placements","description":"List active placements with Yellow or Red risk level.","operationId":"get_at_risk_placements_api_engagement_at_risk_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/engagement/placements/{placement_id}/checkins":{"get":{"tags":["engagement"],"summary":"List Checkins","operationId":"list_checkins_api_engagement_placements__placement_id__checkins_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"placement_id","in":"path","required":true,"schema":{"type":"string","title":"Placement Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["engagement"],"summary":"Create Checkin","operationId":"create_checkin_api_engagement_placements__placement_id__checkins_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"placement_id","in":"path","required":true,"schema":{"type":"string","title":"Placement Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CheckinCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dev-portal/timesheets":{"get":{"tags":["Developer Portal Review"],"summary":"List Timesheets","description":"Timesheets awaiting a decision (default: status=submitted).","operationId":"list_timesheets_api_dev_portal_timesheets_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"default":"submitted","title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dev-portal/time-off":{"get":{"tags":["Developer Portal Review"],"summary":"List Time Off","description":"Time-off requests awaiting a decision (default: status=pending).","operationId":"list_time_off_api_dev_portal_time_off_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"default":"pending","title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dev-portal/timesheets/{timesheet_id}/decision":{"post":{"tags":["Developer Portal Review"],"summary":"Decide Timesheet","description":"Approve or send back one timesheet, then fan out to the engineer.","operationId":"decide_timesheet_api_dev_portal_timesheets__timesheet_id__decision_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"timesheet_id","in":"path","required":true,"schema":{"type":"string","title":"Timesheet Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/dev-portal/time-off/{request_id}/decision":{"post":{"tags":["Developer Portal Review"],"summary":"Decide Time Off","description":"Approve or decline one PTO request, then fan out to the engineer\n(and, on approval, to the client's Slack channel).","operationId":"decide_time_off_api_dev_portal_time_off__request_id__decision_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/invoices":{"get":{"tags":["invoices"],"summary":"List Invoices","description":"List invoices\n\nFounders see all invoices\nClient users see only their company's invoices","operationId":"list_invoices_api_invoices_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"client_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by client","title":"Client Id"},"description":"Filter by client"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceResponse"},"title":"Response List Invoices Api Invoices Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["invoices"],"summary":"Create Invoice","description":"Create and send invoice (founder only)\n\nCreates invoice in database and Stripe, then sends email","operationId":"create_invoice_api_invoices_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/invoices/overdue":{"get":{"tags":["invoices"],"summary":"Get Overdue Invoices","description":"Get all overdue invoices (founder only)\n\nReturns invoices with status != Paid and due_date in past","operationId":"get_overdue_invoices_api_invoices_overdue_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/InvoiceResponse"},"type":"array","title":"Response Get Overdue Invoices Api Invoices Overdue Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/invoices/pending":{"get":{"tags":["invoices"],"summary":"Get Pending Invoices","description":"Get all draft invoices pending CEO review (founder only).\n\nThese are auto-generated invoices waiting for approval before\nbeing sent to Stripe and emailed to clients.","operationId":"get_pending_invoices_api_invoices_pending_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/InvoiceResponse"},"type":"array","title":"Response Get Pending Invoices Api Invoices Pending Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/invoices/{invoice_id}":{"get":{"tags":["invoices"],"summary":"Get Invoice","description":"Get single invoice by ID","operationId":"get_invoice_api_invoices__invoice_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"invoice_id","in":"path","required":true,"schema":{"type":"string","title":"Invoice Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["invoices"],"summary":"Update Invoice","description":"Update invoice (founder only)\n\nTypically used to mark as Paid manually","operationId":"update_invoice_api_invoices__invoice_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"invoice_id","in":"path","required":true,"schema":{"type":"string","title":"Invoice Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"New status","title":"Status"},"description":"New status"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/invoices/generate":{"post":{"tags":["invoices"],"summary":"Trigger Invoice Generation","description":"Manually trigger monthly invoice generation (founder only).\n\nSame logic as the monthly cron job — generates Draft invoices\nfor all active placements with billing_start_date <= today.\nUseful for testing or running mid-month.","operationId":"trigger_invoice_generation_api_invoices_generate_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/invoices/{invoice_id}/approve":{"post":{"tags":["invoices"],"summary":"Approve And Send Invoice","description":"Approve a draft invoice and send via Stripe (founder only).\n\nThis is the CEO approval step — converts Draft → Sent.\nCreates the Stripe invoice and emails the client.","operationId":"approve_and_send_invoice_api_invoices__invoice_id__approve_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"invoice_id","in":"path","required":true,"schema":{"type":"string","title":"Invoice Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/invoices/{invoice_id}/send":{"post":{"tags":["invoices"],"summary":"Send Invoice","description":"Send invoice email (founder only)\n\nFor invoices that weren't auto-sent","operationId":"send_invoice_api_invoices__invoice_id__send_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"invoice_id","in":"path","required":true,"schema":{"type":"string","title":"Invoice Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoiceResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/invoices/{invoice_id}/remind":{"post":{"tags":["invoices"],"summary":"Send Payment Reminder","description":"Send payment reminder email (founder only)\n\nFor overdue invoices","operationId":"send_payment_reminder_api_invoices__invoice_id__remind_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"invoice_id","in":"path","required":true,"schema":{"type":"string","title":"Invoice Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Send Payment Reminder Api Invoices  Invoice Id  Remind Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/invoices/{invoice_id}/document":{"get":{"tags":["invoices"],"summary":"Get Invoice Document Html","description":"Get invoice as a rendered HTML document.\n\nReturns a printable, professional invoice page.\nClients can print or save as PDF from their browser.","operationId":"get_invoice_document_html_api_invoices__invoice_id__document_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"invoice_id","in":"path","required":true,"schema":{"type":"string","title":"Invoice Id"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/invoices/{invoice_id}/document/pdf":{"get":{"tags":["invoices"],"summary":"Get Invoice Document Pdf","description":"Download invoice as a PDF file.\n\nGenerates a professional PDF invoice document.\nRequires weasyprint to be installed.","operationId":"get_invoice_document_pdf_api_invoices__invoice_id__document_pdf_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"invoice_id","in":"path","required":true,"schema":{"type":"string","title":"Invoice Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payments/webhook":{"post":{"tags":["payments"],"summary":"Stripe Webhook","description":"Stripe webhook endpoint — syncs ALL event data to Neon.\n\nHandles:\n- invoice.payment_succeeded\n- invoice.payment_failed\n- customer.subscription.updated\n- customer.subscription.deleted","operationId":"stripe_webhook_api_payments_webhook_post","parameters":[{"name":"stripe-signature","in":"header","required":false,"schema":{"type":"string","title":"Stripe-Signature"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payments/methods/{customer_id}":{"get":{"tags":["payments"],"summary":"List Payment Methods","description":"Get all payment methods for a customer from DB (founder only).","operationId":"list_payment_methods_api_payments_methods__customer_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"customer_id","in":"path","required":true,"schema":{"type":"string","title":"Customer Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/payments/methods":{"post":{"tags":["payments"],"summary":"Attach Payment Method","description":"Attach payment method to customer and sync to DB (founder only).","operationId":"attach_payment_method_api_payments_methods_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"customer_id","in":"query","required":true,"schema":{"type":"string","title":"Customer Id"}},{"name":"payment_method_id","in":"query","required":true,"schema":{"type":"string","title":"Payment Method Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/wise/transfer":{"post":{"tags":["wise"],"summary":"Create Single Transfer","description":"Create single engineer payment via Wise (founder only)\n\nProcess:\n1. Get candidate bank details from database\n2. Create quote for exchange rate\n3. Create transfer\n4. Fund transfer from Wise balance\n5. Record payment in database","operationId":"create_single_transfer_api_wise_transfer_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TransferResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/wise/batch-transfer":{"post":{"tags":["wise"],"summary":"Create Batch Transfer","description":"Process batch payments to multiple engineers (founder only)\n\nTypically run monthly on the 1st","operationId":"create_batch_transfer_api_wise_batch_transfer_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchTransferRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchTransferResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/wise/transfer/{transfer_id}":{"get":{"tags":["wise"],"summary":"Get Transfer Status","description":"Get Wise transfer status (founder only)","operationId":"get_transfer_status_api_wise_transfer__transfer_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"transfer_id","in":"path","required":true,"schema":{"type":"string","title":"Transfer Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/wise/balance":{"get":{"tags":["wise"],"summary":"Get Wise Balance","description":"Get Wise account balance (founder only)","operationId":"get_wise_balance_api_wise_balance_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/finance/dashboard":{"get":{"tags":["finance"],"summary":"Finance Dashboard","description":"Platform-level finance stats: MRR, margin, AR.","operationId":"finance_dashboard_api_finance_dashboard_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/finance/placements/{placement_id}/margin":{"get":{"tags":["finance"],"summary":"Get Placement Margin","description":"Single placement gross margin.","operationId":"get_placement_margin_api_finance_placements__placement_id__margin_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"placement_id","in":"path","required":true,"schema":{"type":"string","title":"Placement Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/finance/companies/{company_id}/pnl":{"get":{"tags":["finance"],"summary":"Get Company Pnl","description":"Aggregate P&L for a company in a billing period.","operationId":"get_company_pnl_api_finance_companies__company_id__pnl_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"company_id","in":"path","required":true,"schema":{"type":"string","title":"Company Id"}},{"name":"billing_period","in":"query","required":true,"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}$","title":"Billing Period"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/finance/reconciliation/{period}":{"get":{"tags":["finance"],"summary":"Get Reconciliation Report","description":"Get all reconciliation records for a billing period.","operationId":"get_reconciliation_report_api_finance_reconciliation__period__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"period","in":"path","required":true,"schema":{"type":"string","title":"Period"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/finance/reconciliation/{period}/run":{"post":{"tags":["finance"],"summary":"Run Reconciliation","description":"Trigger reconciliation for all companies in a billing period.","operationId":"run_reconciliation_api_finance_reconciliation__period__run_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"period","in":"path","required":true,"schema":{"type":"string","title":"Period"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/finance/discrepancies/{period}":{"get":{"tags":["finance"],"summary":"Get Discrepancies","description":"List margin discrepancies (missing cost/revenue, negative margin).","operationId":"get_discrepancies_api_finance_discrepancies__period__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"period","in":"path","required":true,"schema":{"type":"string","title":"Period"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/finance/contractor-payments":{"post":{"tags":["finance"],"summary":"Create Contractor Payment","description":"Record a contractor payment manually.","operationId":"create_contractor_payment_api_finance_contractor_payments_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContractorPaymentCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["finance"],"summary":"List Contractor Payments","description":"List contractor payments with optional filters.","operationId":"list_contractor_payments_api_finance_contractor_payments_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"placement_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Placement Id"}},{"name":"billing_period","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Period"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/deel/contracts":{"post":{"tags":["deel"],"summary":"Create Deel Contract","description":"Create a Deel EOR contract for a placement.","operationId":"create_deel_contract_api_deel_contracts_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeelContractCreate"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/deel/contracts/{contract_id}":{"get":{"tags":["deel"],"summary":"Get Deel Contract","description":"Get a Deel contract by ID.","operationId":"get_deel_contract_api_deel_contracts__contract_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"contract_id","in":"path","required":true,"schema":{"type":"string","title":"Contract Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/deel/contracts/{contract_id}/terminate":{"post":{"tags":["deel"],"summary":"Terminate Deel Contract","description":"Terminate a Deel contract.","operationId":"terminate_deel_contract_api_deel_contracts__contract_id__terminate_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"contract_id","in":"path","required":true,"schema":{"type":"string","title":"Contract Id"}},{"name":"reason","in":"query","required":false,"schema":{"type":"string","default":"","title":"Reason"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/deel/invoices":{"get":{"tags":["deel"],"summary":"List Deel Invoices","description":"List Deel invoices (cost side).","operationId":"list_deel_invoices_api_deel_invoices_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"contract_id","in":"query","required":false,"schema":{"type":"string","title":"Contract Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/deel/sync-payments":{"post":{"tags":["deel"],"summary":"Sync Deel Payments Endpoint","description":"Pull Deel payments into contractor_payments table.","operationId":"sync_deel_payments_endpoint_api_deel_sync_payments_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/deel/webhooks":{"post":{"tags":["deel"],"summary":"Deel Webhook","description":"Receive Deel webhook events.","operationId":"deel_webhook_api_deel_webhooks_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/factory/projects":{"get":{"tags":["factory"],"summary":"List Factory Projects","description":"List all factory projects with optional filters.","operationId":"list_factory_projects_api_factory_projects_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"company_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["factory"],"summary":"Create Factory Project","description":"Create a new factory project (founder only).","operationId":"create_factory_project_api_factory_projects_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactoryProjectCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/factory/projects/{project_id}":{"get":{"tags":["factory"],"summary":"Get Factory Project","description":"Get factory project with milestones and progress.","operationId":"get_factory_project_api_factory_projects__project_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["factory"],"summary":"Update Factory Project","description":"Update a factory project.","operationId":"update_factory_project_api_factory_projects__project_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactoryProjectUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/factory/projects/{project_id}/milestones":{"post":{"tags":["factory"],"summary":"Create Factory Milestone","description":"Add a milestone to a factory project.","operationId":"create_factory_milestone_api_factory_projects__project_id__milestones_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactoryMilestoneCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/factory/milestones/{milestone_id}":{"patch":{"tags":["factory"],"summary":"Update Factory Milestone","description":"Update a milestone.","operationId":"update_factory_milestone_api_factory_milestones__milestone_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"milestone_id","in":"path","required":true,"schema":{"type":"string","title":"Milestone Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactoryMilestoneUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/factory/milestones/{milestone_id}/submit":{"post":{"tags":["factory"],"summary":"Submit Factory Milestone","description":"Submit a milestone for client review.","operationId":"submit_factory_milestone_api_factory_milestones__milestone_id__submit_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"milestone_id","in":"path","required":true,"schema":{"type":"string","title":"Milestone Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/factory/projects/{project_id}/updates":{"get":{"tags":["factory"],"summary":"List Factory Updates","description":"List updates for a factory project (newest first).","operationId":"list_factory_updates_api_factory_projects__project_id__updates_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["factory"],"summary":"Create Factory Update","description":"Post a progress update for a factory project.","operationId":"create_factory_update_api_factory_projects__project_id__updates_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactoryUpdateCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/factory/milestones/{milestone_id}/deliverables":{"post":{"tags":["factory"],"summary":"Create Factory Deliverable","description":"Add a deliverable to a milestone.","operationId":"create_factory_deliverable_api_factory_milestones__milestone_id__deliverables_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"milestone_id","in":"path","required":true,"schema":{"type":"string","title":"Milestone Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactoryDeliverableCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/factory/milestones/{milestone_id}/invoice":{"post":{"tags":["factory"],"summary":"Create Milestone Invoice","description":"Generate a Stripe invoice for an accepted milestone.","operationId":"create_milestone_invoice_api_factory_milestones__milestone_id__invoice_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"milestone_id","in":"path","required":true,"schema":{"type":"string","title":"Milestone Id"}}],"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/profile":{"get":{"tags":["candidate-profiles"],"summary":"Get Profile Html","description":"Render candidate profile as HTML preview. No audit (preview-only).","operationId":"get_profile_html_api_candidates__candidate_id__profile_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}},{"name":"blind","in":"query","required":false,"schema":{"type":"boolean","description":"Hide candidate name and company","default":false,"title":"Blind"},"description":"Hide candidate name and company"},{"name":"project_candidate_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Project candidate ID for context","title":"Project Candidate Id"},"description":"Project candidate ID for context"}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/profile/pdf":{"get":{"tags":["candidate-profiles"],"summary":"Get Profile Pdf","description":"Download candidate profile as PDF.\n\nL5: writes a document_access_log row keyed by a freshly-generated\ntrack_id that's also printed as the PDF watermark.","operationId":"get_profile_pdf_api_candidates__candidate_id__profile_pdf_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}},{"name":"blind","in":"query","required":false,"schema":{"type":"boolean","description":"Hide candidate name and company","default":false,"title":"Blind"},"description":"Hide candidate name and company"},{"name":"project_candidate_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Project candidate ID for context","title":"Project Candidate Id"},"description":"Project candidate ID for context"},{"name":"project_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional project ID for audit log scoping","title":"Project Id"},"description":"Optional project ID for audit log scoping"},{"name":"client_company_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Optional client company ID for audit attribution","title":"Client Company Id"},"description":"Optional client company ID for audit attribution"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/resume":{"post":{"tags":["candidate-resume"],"summary":"Upload And Parse Resume","description":"Upload a resume file (PDF) or paste resume text.\nStores file in R2, extracts text, parses with Claude, and updates candidate profile.","operationId":"upload_and_parse_resume_api_candidates__candidate_id__resume_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_and_parse_resume_api_candidates__candidate_id__resume_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/resume/reparse-missing":{"post":{"tags":["candidate-resume"],"summary":"Reparse Missing Resumes","description":"Re-parse stored R2 resumes for candidates whose work history is EMPTY.\n\nFill-only by construction: it selects candidates with no\nexperience_entries, so it can never overwrite a parsed profile. Exists to\nrecover the .docx resumes the apply form used to decode as UTF-8 (and\nPDFs whose first parse failed). Newest first, ≤25 per call so one request\nstays well inside the HTTP timeout; call repeatedly until ``remaining``\nis 0. Legacy .doc is skipped (unsupported). A resume that fails again\nstays eligible, so pass ``offset`` += (attempted - parsed) to step past it.","operationId":"reparse_missing_resumes_api_candidates_resume_reparse_missing_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"dry_run","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Dry Run"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/interview":{"post":{"tags":["interviews"],"summary":"Create Interview Assessment","description":"Create a new interview assessment for a candidate.\n\nComputes the weighted total (40/30/20/10) server-side, inserts the row,\nand updates the candidate's denormalized cache columns in one transaction.","operationId":"create_interview_assessment_api_candidates__candidate_id__interview_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewAssessmentCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewAssessmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/interviews":{"get":{"tags":["interviews"],"summary":"List Interview Assessments","description":"List all assessments for a candidate, most recent first.","operationId":"list_interview_assessments_api_candidates__candidate_id__interviews_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InterviewAssessmentResponse"},"title":"Response List Interview Assessments Api Candidates  Candidate Id  Interviews Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/interviews/{assessment_id}":{"get":{"tags":["interviews"],"summary":"Get Interview Assessment","operationId":"get_interview_assessment_api_interviews__assessment_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"assessment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Assessment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewAssessmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["interviews"],"summary":"Update Interview Assessment","description":"Update an existing assessment.\n\nIf any score field is provided, weighted_total is recomputed using\nexisting values for the missing scores. The candidate cache is\nrefreshed only if this assessment is still the most recent one.","operationId":"update_interview_assessment_api_interviews__assessment_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"assessment_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Assessment Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewAssessmentUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewAssessmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/score-for-project/{project_id}":{"post":{"tags":["fit-scoring"],"summary":"Score Candidate For Project","description":"Compute (or fetch cached) fit score for this candidate↔project pair.","operationId":"score_candidate_for_project_api_candidates__candidate_id__score_for_project__project_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}},{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}},{"name":"force","in":"query","required":false,"schema":{"type":"boolean","description":"Bypass cache and re-score","default":false,"title":"Force"},"description":"Bypass cache and re-score"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FitScoreResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/ranked-candidates":{"get":{"tags":["fit-scoring"],"summary":"List Ranked Candidates","description":"Top candidates for this project by fit score, archived ones excluded.","operationId":"list_ranked_candidates_api_projects__project_id__ranked_candidates_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RankedCandidate"},"title":"Response List Ranked Candidates Api Projects  Project Id  Ranked Candidates Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/send-assessment":{"post":{"tags":["assessments"],"summary":"Send Assessment Endpoint","description":"Persist the pasted code-challenge link and email it to the candidate.\n\nEmail failure is fatal — we don't want a sent-but-undelivered ghost row.\nRoll back the DB write so Roberto can retry cleanly.","operationId":"send_assessment_endpoint_api_candidates__candidate_id__send_assessment_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__models__assessment__SendAssessmentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/record-assessment-result":{"post":{"tags":["assessments"],"summary":"Record Assessment Result Endpoint","description":"Paste the percentile (and optional override) → service auto-routes.","operationId":"record_assessment_result_endpoint_api_candidates__candidate_id__record_assessment_result_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordAssessmentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/assessment":{"get":{"tags":["assessments"],"summary":"Get Assessment Endpoint","operationId":"get_assessment_endpoint_api_candidates__candidate_id__assessment_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/interview-templates":{"get":{"tags":["interview-templates"],"summary":"List Templates","description":"List templates. Hides inactive by default — `?include_inactive=true`\nto show soft-deleted ones (admin/audit use).","operationId":"list_templates_api_interview_templates_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"include_inactive","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Inactive"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InterviewTemplateResponse"},"title":"Response List Templates Api Interview Templates Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["interview-templates"],"summary":"Create Template","operationId":"create_template_api_interview_templates_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewTemplateCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewTemplateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/interview-templates/{template_id}":{"get":{"tags":["interview-templates"],"summary":"Get Template","operationId":"get_template_api_interview_templates__template_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewTemplateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["interview-templates"],"summary":"Update Template","description":"Update meta and/or replace questions wholesale.\n\nQuestion replace is a delete-and-recreate to keep order_index ints clean.\nExisting candidate_interviews referencing the OLD question rows would\nkeep their question_id FK fine — Postgres won't cascade because we\ndon't ON DELETE on interview_responses.question_id. Once a question is\ndeleted from the template, in-flight interviews still display the old\nquestion_text from the response row's joined data... wait, they don't.\nExisting responses keep their question_id, but the question row is gone.\nFor V1: don't allow editing questions on a template that has any\nin-flight interviews. Simpler than versioning.","operationId":"update_template_api_interview_templates__template_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewTemplateUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewTemplateResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["interview-templates"],"summary":"Soft Delete Template","description":"Soft delete — sets is_active=false. Hard delete blocked because\ncandidate_interviews FK to template_id and we want history preserved.","operationId":"soft_delete_template_api_interview_templates__template_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"template_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Template Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/send-interview":{"post":{"tags":["async-interviews"],"summary":"Send Interview","description":"Create an interview row + magic token + email the candidate.\n\nOn email failure: rollback the DB write so we don't leak a sent-but-\nundelivered ghost row (matches L3's send-assessment pattern).","operationId":"send_interview_api_candidates__candidate_id__send_interview_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendInterviewRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InterviewSummary"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/async-interviews":{"get":{"tags":["async-interviews"],"summary":"List Candidate Interviews","operationId":"list_candidate_interviews_api_candidates__candidate_id__async_interviews_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/InterviewSummary"},"title":"Response List Candidate Interviews Api Candidates  Candidate Id  Async Interviews Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/async-interviews/{interview_id}":{"get":{"tags":["async-interviews"],"summary":"Get Interview Detail","description":"Recruiter detail — includes transcripts, scores, signed video URLs.","operationId":"get_interview_detail_api_async_interviews__interview_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"interview_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Interview Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateInterviewResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/async-interviews/{interview_id}/mark-reviewed":{"post":{"tags":["async-interviews"],"summary":"Mark Reviewed","operationId":"mark_reviewed_api_async_interviews__interview_id__mark_reviewed_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"interview_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Interview Id"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/async-interviews/{interview_id}/responses/{response_id}/reprocess":{"post":{"tags":["async-interviews"],"summary":"Reprocess Response","description":"Re-run the ffmpeg → Whisper → Claude pipeline for a failed response.\n\nResets processing_status to 'pending' synchronously, fires the actual\npipeline as a BackgroundTask. Caller should poll the detail endpoint.","operationId":"reprocess_response_api_async_interviews__interview_id__responses__response_id__reprocess_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"interview_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Interview Id"}},{"name":"response_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Response Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/async-interviews/{interview_id}/reprocess-failed":{"post":{"tags":["async-interviews"],"summary":"Reprocess All Failed","description":"Retry every failed response on this interview in one shot.\n\nUseful after a transient infrastructure fix (e.g., OPENAI_API_KEY added\nto Railway env vars) — bulk-reset everything that was stuck on the\nsame upstream issue.\n\nReturns the count of responses queued for retry. Each row is reset to\nprocessing_status='pending' synchronously and processed asynchronously\nvia BackgroundTasks.","operationId":"reprocess_all_failed_api_async_interviews__interview_id__reprocess_failed_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"interview_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Interview Id"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/interview/{magic_token}":{"get":{"tags":["public-interview"],"summary":"Get Public Interview","description":"Resolve a magic-link token → interview state for the candidate.","operationId":"get_public_interview_interview__magic_token__get","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicInterviewView"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/interview/{magic_token}/questions/{question_id}/reveal":{"post":{"tags":["public-interview"],"summary":"Reveal Question","description":"Check I: reveal ONE question's text, in plan order.\n\n404 unless INTERVIEW_QUESTION_GATING_ENABLED is on for this interview\n(video template with a question plan). The first reveal is stamped and\nkept: a refresh re-reveals the same question without moving the stamp,\nso the reveal->record latency is measured from the first sight of it.\nRequires the AIVIA consent, like the upload: the question is the start\nof the recorded interview.","operationId":"reveal_question_interview__magic_token__questions__question_id__reveal_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}},{"name":"question_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Question Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicQuestionReveal"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/interview/{magic_token}/ai-notice-consent":{"post":{"tags":["public-interview"],"summary":"Accept Ai Notice","description":"Record the candidate's consent to AI analysis of their recording.\n\nCalled once, before the first recording, when the candidate ticks the\ndisclosure checkbox. Idempotent — a second call keeps the original\ntimestamp.","operationId":"accept_ai_notice_interview__magic_token__ai_notice_consent_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/interview/{magic_token}/training-consent":{"post":{"tags":["public-interview"],"summary":"Accept Training Consent","description":"Record the candidate's OPTIONAL opt-in to model improvement.\n\nIdempotent: a repeat keeps the first timestamp; consenting again after a\nwithdrawal clears the withdrawal and re-stamps.","operationId":"accept_training_consent_interview__magic_token__training_consent_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/interview/{magic_token}/training-consent/withdraw":{"post":{"tags":["public-interview"],"summary":"Withdraw Training Consent","description":"Withdraw the optional opt-in. Idempotent; allowed at any time,\nincluding after the interview is complete or the link has expired.","operationId":"withdraw_training_consent_interview__magic_token__training_consent_withdraw_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/interview/{magic_token}/answers/{question_id}":{"post":{"tags":["public-interview"],"summary":"Submit Typed Answer","description":"Save + score one TYPED answer.\n\nSibling of the video upload below, for interviews on a `typed` template.\nSame token contract, same rubric, same scorer — the candidate types\ninstead of recording, which is the entire difference. Scoring is inline\n(a Claude call on a few hundred words, no media pipeline), so the\ncandidate's next question loads already knowing this one landed.\n\nTHIS IS THE ONLY UNAUTHENTICATED ENDPOINT THAT SPENDS ANTHROPIC TOKENS\nON ARBITRARY INPUT, so it carries two brakes the video path does not\nneed (video goes through a queue and a media pipeline that rate-limits\nitself by physics). The limit is generous against real use — an\ninterview is four questions and people take minutes per answer, so 12\na minute is roughly 3x the fastest legitimate pace — and cheap against\na script pointed at one leaked token. The flag is the second brake.","operationId":"submit_typed_answer_interview__magic_token__answers__question_id__post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}},{"name":"question_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Question Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TypedAnswerIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/interview/{magic_token}/responses/{question_id}":{"post":{"tags":["public-interview"],"summary":"Upload Response","description":"Upload a video file for one question.\n\nOn success: kicks off background processing (ffmpeg → Whisper → Claude).\nThe candidate sees an immediate ack; scoring lands later.","operationId":"upload_response_interview__magic_token__responses__question_id__post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}},{"name":"question_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Question Id"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_response_interview__magic_token__responses__question_id__post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicResponseAck"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/opt-out/{token}":{"get":{"tags":["public-optout"],"summary":"Candidate Opt Out Click","description":"One-click opt-out from an email footer link. Renders the same page\nfor unknown tokens so a crawler can't tell which are real.","operationId":"candidate_opt_out_click_api_candidates_opt_out__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["public-optout"],"summary":"Candidate Opt Out Apply","description":"Programmatic / RFC 8058 one-click opt-out. Idempotent.","operationId":"candidate_opt_out_apply_api_candidates_opt_out__token__post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OptOutStatus"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/leads/opt-out/{token}":{"get":{"tags":["public-optout"],"summary":"Lead Opt Out Page","description":"Confirm page for the footer link. Does NOT apply — see module doc\n(corporate link scanners GET every URL). Same page for any token.","operationId":"lead_opt_out_page_api_leads_opt_out__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["public-optout"],"summary":"Lead Opt Out Apply","description":"Applies the unsubscribe. Idempotent.\n\nThree callers: the confirm page's form (human → HTML reply), Gmail /\nYahoo one-click (machine → JSON), and tools / tests (JSON → JSON).","operationId":"lead_opt_out_apply_api_leads_opt_out__token__post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/share/opt-out/{token}":{"get":{"tags":["public-optout"],"summary":"Share Opt Out Page","description":"Confirm page. Does NOT apply — same reason as the lead endpoint.\n\nThis address is a corporate mailbox by construction (it is a colleague\nof the buyer), so it sits behind exactly the SafeLinks / Proofpoint /\nMimecast scanners that GET every URL on delivery. Applying on GET here\nwould unsubscribe a share recipient before they opened the mail.","operationId":"share_opt_out_page_api_shortlist_share_opt_out__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["public-optout"],"summary":"Share Opt Out Apply","description":"Applies the unsubscribe. Idempotent, and neutral about bad tokens.\n\nThree callers, same as the lead endpoint: the confirm form (human →\nHTML), Gmail / Yahoo RFC 8058 one-click (machine → JSON), and JSON\ntooling. Nothing here may 422 — a 422 breaks the native inbox button.","operationId":"share_opt_out_apply_api_shortlist_share_opt_out__token__post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/vetting/requests":{"post":{"tags":["vetting"],"summary":"Create Vetting Request","description":"Create a vetting request. Returns the links the requester forwards.","operationId":"create_vetting_request_api_vetting_requests_post","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VettingRequestIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["vetting-admin"],"summary":"List Vetting Requests","description":"Recent requests with a count of frozen percentile rows each, and how\noften each request's candidate links were replaced / progress discarded.","operationId":"list_vetting_requests_api_vetting_requests_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/vetting/config":{"get":{"tags":["vetting"],"summary":"Get Config","description":"What the www form should render. Never 404s, so the page can ask\nbefore deciding whether to show the code step; nothing here is secret\n(both values are visible from the behaviour of the other routes).","operationId":"get_config_api_vetting_config_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/vetting/verify/request":{"post":{"tags":["vetting"],"summary":"Web Verify Request","description":"Email a 6-digit code to the work address. Always the same answer for\na valid work email (sent, or withheld by a limit: buyer_verification\n#478 M1), so the page cannot be used to probe who has an account.","operationId":"web_verify_request_api_vetting_verify_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebVerifyRequestIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/vetting/verify/confirm":{"post":{"tags":["vetting"],"summary":"Web Verify Confirm","description":"The code confirms the one verification it was emailed for (attempts\ncapped per verification). Returns the buyer token the page sends with\nPOST /requests; it is held in memory by the page, never in storage.","operationId":"web_verify_confirm_api_vetting_verify_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebVerifyConfirmIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/vetting/share/{token}":{"get":{"tags":["vetting"],"summary":"Get Share","description":"Candidate-facing: who is asking, for what role, and have I consented.\n\nREAD-ONLY (PR #472 security review L4): a link preview (Slack / email\nunfurl bots) must not start the 14-day clock or use up the 72-hour\nwindow. Only the candidate's explicit \"Start\" (POST .../consent) binds\nthe browser and starts the clock. ``bk`` is the page's per-browser key:\na single-use link (D1/D2) already started in another browser is refused.\nOther links ignore it.","operationId":"get_share_api_vetting_share__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/vetting/share/{token}/consent":{"post":{"tags":["vetting"],"summary":"Post Consent","description":"Candidate consents and receives their assessment links.","operationId":"post_consent_api_vetting_share__token__consent_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsentIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/vetting/share/{token}/decline":{"post":{"tags":["vetting"],"summary":"Post Decline","description":"Candidate: \"Not interested\" (PR #528 privacy L3). Stops the one\nreminder; the requester's status page shows it. Idempotent.","operationId":"post_decline_api_vetting_share__token__decline_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/vetting/status/{token}":{"get":{"tags":["vetting"],"summary":"Get Status","description":"Requester-facing progress. State, not content.\n\nRaw scores and their bar (after delivery): always for our own services\n(MCP get_vetting_status, Sol: proxy token), for the public page only\nwhile VETTING_WEB_VERIFY_ENABLED is on (decision D3 ships dark; round 2:\nprivacy N4 gated the page but not the API, scr NEW-5 coupled MCP to the\nweb flag).","operationId":"get_status_api_vetting_status__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/vetting/status/{token}/candidates/{candidate_id}/new-link":{"post":{"tags":["vetting"],"summary":"Reissue Candidate Link","description":"Requester-side (status token): a new single-use candidate link, for a\ncandidate whose link was started in another browser or never opened in\ntime (D2). The old link, and the coding / interview links it handed out,\nstop working; nothing is emailed. Live for MCP single-use links whatever\nthe web flags say (they are single-use in production already).\n\n``candidate_id`` is a plain string, checked AFTER the kill switch: with\nVETTING_ENABLED off the route answers 404 like every other, and a\nmalformed id is 404 too, never a 422 that confirms the route exists\n(round 3, L4).","operationId":"reissue_candidate_link_api_vetting_status__token__candidates__candidate_id__new_link_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","title":"Candidate Id"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/ReissueIn"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/vetting/requests/{request_id}/percentiles":{"get":{"tags":["vetting-admin"],"summary":"Get Request Percentiles","description":"Raw frozen rows (cell, n, mode, gate_reason, method_version) for audit.","operationId":"get_request_percentiles_api_vetting_requests__request_id__percentiles_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Request Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/standout-badges":{"get":{"tags":["vetting-admin"],"summary":"Get Standout Badges","description":"INTERNAL ONLY. ``{\"enabled\": bool, \"badges\": {candidate_id: badge}}``.\n\n``enabled`` false (and no badges) while CRM_STANDOUT_BADGE_ENABLED is off,\nso the dashboard renders nothing without a redeploy.","operationId":"get_standout_badges_api_standout_badges_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_ids","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Comma-separated UUIDs","title":"Candidate Ids"},"description":"Comma-separated UUIDs"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/public/bench":{"get":{"tags":["public-bench"],"summary":"Get Public Bench","description":"The live bench payload.\n\nRate limit is generous because the expected caller is one Next.js ISR\nrevalidation every few minutes, not a browser — but the route is on the\nopen internet, so it is not unlimited.\n\nA DB failure returns the self-hiding state rather than a 500: a marketing\npage that renders its \"tell us the role\" fallback during an incident is\nstrictly better than one that renders an error to paid traffic.","operationId":"get_public_bench_api_public_bench_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicBenchOut"}}}}}}},"/api/public/speed-receipt":{"get":{"tags":["public-bench"],"summary":"Get Speed Receipt","description":"Read the nightly-computed receipt.\n\nA read, never a computation: the number must not move between the page\na buyer reads and the email they forward five minutes later. The\nnightly tick (``/api/internal/cron/speed-receipt-tick``) is the only\nwriter.","operationId":"get_speed_receipt_api_public_speed_receipt_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpeedReceiptOut"}}}}}}},"/api/public/bench-bar-stat":{"get":{"tags":["public-bench"],"summary":"Get Bench Bar Stat","description":"Cached in-process for an hour; never 500s.","operationId":"get_bench_bar_stat_api_public_bench_bar_stat_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BenchBarStatOut"}}}}}}},"/api/public/agent-feeds":{"get":{"tags":["agent-feeds"],"summary":"Agent Feeds Status","description":"Runtime flags + this environment's URLs. 404 while BOTH halves are\noff, so the dark feature stays indistinguishable from a missing one\n(r2 security N6); www reads a 404 as \"nothing is live\".","operationId":"agent_feeds_status_api_public_agent_feeds_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/public/availability":{"get":{"tags":["agent-feeds"],"summary":"Get Availability","description":"The feed document (see ``availability_feed_service``). Never 500s:\na failure is ``published: false`` with no cells.","operationId":"get_availability_api_public_availability_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/public/jobs/intake":{"post":{"tags":["agent-feeds"],"summary":"Intake Job Posting","description":"schema.org JobPosting JSON-LD → vetted shortlist request.\n\nOrder: flag (404) → per-IP limit (429, before auth so token guessing is\nthrottled too) → body size/JSON (413/400) → buyer token (401/503) →\npersonal inbox (400) → JobPosting mapping (422, every field error at\nonce) → per-email + per-domain daily slot (429) → the shared shortlist\npath (201; 200 for a duplicate, which hands its slot back). Every\nrefusal, including a failure inside the shortlist path, answers in the\ndocumented ``{\"detail\": {code, message, docs, next_step?}}`` envelope.","operationId":"intake_job_posting_api_public_jobs_intake_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/public/role-feasibility":{"get":{"tags":["public-role-feasibility"],"summary":"Get Role Feasibility","operationId":"get_role_feasibility_api_public_role_feasibility_get","parameters":[{"name":"role","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role"}},{"name":"stack","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stack"}},{"name":"seniority","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seniority"}},{"name":"seat_budget","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seat Budget"}},{"name":"needed_by","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Needed By"}},{"name":"count","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Count"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Role Feasibility Api Public Role Feasibility Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/send-coding-assessment":{"post":{"tags":["coding-assessment"],"summary":"Send Coding Assessment","description":"Mint a magic link and email the candidate. Rolls back the row on email\nsend failure so we don't leak a sent-but-undelivered ghost row.","operationId":"send_coding_assessment_api_candidates__candidate_id__send_coding_assessment_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/app__models__coding_challenge__SendAssessmentRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/coding-assessment":{"get":{"tags":["coding-assessment"],"summary":"Get Candidate Coding Assessment","operationId":"get_candidate_coding_assessment_api_candidates__candidate_id__coding_assessment_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/RecruiterAssessmentView"},{"type":"null"}],"title":"Response Get Candidate Coding Assessment Api Candidates  Candidate Id  Coding Assessment Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-challenges":{"get":{"tags":["coding-assessment"],"summary":"List Coding Challenges","operationId":"list_coding_challenges_api_coding_challenges_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ChallengeSummary"},"type":"array","title":"Response List Coding Challenges Api Coding Challenges Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/assessment-packages":{"get":{"tags":["coding-assessment"],"summary":"List Assessment Packages","description":"Recruiter dropdown for picking the package on a candidate Send or\nsetting a project's default_package_slug.\n\n`kind = 'role'` keeps this list byte-identical to what it returned before\nWave 3 A1. The 12 skill atoms are also `is_seed`, so without the filter\nthey would appear here the moment the taxonomy migration runs — with\n`challenge_count = 0` AND `question_count = 0`, i.e. picking one would\nraise `AssessmentStateError` in `create_assessment`. PR-5 exposes atoms\nhere deliberately, once they have content.\n\nSince w3a2qonly a package is startable when it has a challenge OR a\nquestion, so the recruiter picker reads both counts — `engineering-manager`\nis legitimately `challenge_count = 0, question_count = 5`.","operationId":"list_assessment_packages_api_assessment_packages_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/coding-assessment/{magic_token}":{"get":{"tags":["coding-assessment"],"summary":"Get Public Assessment","description":"Public — no auth. Strips hidden tests.","operationId":"get_public_assessment_api_coding_assessment__magic_token__get","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateAssessmentView"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-assessment/{magic_token}/start":{"post":{"tags":["coding-assessment"],"summary":"Start Assessment Public","description":"Explicit \"I'm ready\" — flips sent → in_progress. Opening the page no\nlonger starts the assessment; this click does.","operationId":"start_assessment_public_api_coding_assessment__magic_token__start_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-assessment/{magic_token}/draft":{"patch":{"tags":["coding-assessment"],"summary":"Save Draft Public","description":"Save work in progress and advance the working-time clock.\n\nDrafts lived only in the candidate's localStorage until now, so someone\nwho started on a phone and moved to a laptop lost everything silently.\nThe magic token is the auth, exactly as it is for run and submit.\n\nReturns ``saved: false`` rather than an error when the payload is stale\nor the assessment is already submitted — from the candidate's side\ntheir work is safe either way, and a heartbeat has nothing useful to do\nwith a 4xx.","operationId":"save_draft_public_api_coding_assessment__magic_token__draft_patch","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveDraftRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-assessment/{magic_token}/event":{"post":{"tags":["coding-assessment"],"summary":"Record Event Public","description":"Append one funnel event.\n\n202 and an empty body on every path, including an unknown token or a\nbad event name. This is called from `navigator.sendBeacon` on unload,\nwhich cannot read a response and must never be given a reason to\nretry — and telemetry that can break the page it measures is worse\nthan no telemetry.","operationId":"record_event_public_api_coding_assessment__magic_token__event_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssessmentEventRequest"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-assessment/{magic_token}/run":{"post":{"tags":["coding-assessment"],"summary":"Run Visible","operationId":"run_visible_api_coding_assessment__magic_token__run_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitAssessmentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-assessment/{magic_token}/submit":{"post":{"tags":["coding-assessment"],"summary":"Submit Public","operationId":"submit_public_api_coding_assessment__magic_token__submit_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitAssessmentRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitAssessmentResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bench-profile/{token}":{"get":{"tags":["bench-profile"],"summary":"Get Profile","operationId":"get_profile_api_bench_profile__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["bench-profile"],"summary":"Update Profile","operationId":"update_profile_api_bench_profile__token__patch","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdateRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bench-profile/{token}/visibility":{"get":{"tags":["bench-profile"],"summary":"Get Visibility","description":"The \"Your visibility\" panel — bucketed aggregates, nothing identifying.\n\nDark behind VISIBILITY_PANEL_ENABLED on top of BENCH_PROFILE_ENABLED\n(404 while off, so the page simply doesn't render the panel). The\npayload is an exact allow-list of COUNTS: no timestamps, no lead ids,\nno per-event rows — see visibility_service and\ntests/test_visibility_privacy.py.","operationId":"get_visibility_api_bench_profile__token__visibility_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bench-profile/{token}/card-preview":{"get":{"tags":["bench-profile"],"summary":"Get Card Preview","description":"The card a client sees, shown to the engineer it describes.\n\nA DIFFERENT contract from `/visibility` on purpose. That payload is\ncounts only and carries no name; this one is the candidate's own blind\ncard and carries theirs. Nothing here says which client saw them or\nwhen, and it cannot: `card_preview_service` reads no exposure table.\n\nDark behind CARD_PREVIEW_ENABLED on top of BENCH_PROFILE_ENABLED. The\nsession-authed twin is `GET /api/candidate/card-preview`; both call one\nservice function, so the magic-link door and the account door cannot\ndisagree about what a candidate's card looks like.","operationId":"get_card_preview_api_bench_profile__token__card_preview_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bench-profile/{token}/reissue":{"post":{"tags":["bench-profile"],"summary":"Reissue Eval","description":"Self-serve fresh evaluation link for an expired step (pull-signal —\ndeliberately more generous than the cron's push policy).","operationId":"reissue_eval_api_bench_profile__token__reissue_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReissueBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bench-profile/{token}/resume":{"post":{"tags":["bench-profile"],"summary":"Upload Resume","description":"Resume re-upload: store in R2 + queue the existing Claude re-parse so\nskills/experience refresh from the new document.","operationId":"upload_resume_api_bench_profile__token__resume_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_resume_api_bench_profile__token__resume_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bench-profile/request-link":{"post":{"tags":["bench-profile"],"summary":"Request Link","description":"Always 202 — never reveals whether the email exists.","operationId":"request_link_api_bench_profile_request_link_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestLinkBody"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bench-profile/{token}/assessments":{"get":{"tags":["bench-profile"],"summary":"List Assessments","description":"Catalog: every package with THIS candidate's state per package\n(not_started | active | passed | failed | pending), `available_on` for\na cooldown, `link` for the active one, plus the catalog-level lock and\nthe interview-retake gate.","operationId":"list_assessments_api_bench_profile__token__assessments_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["bench-profile"],"summary":"Start Assessment","description":"Start a package from the profile: gate → eligibility → row with\nsource='self_serve' → invite email (email-first, rollback on failure)\n→ 202 {link}. 409 carries {reason, available_on} for the locked state.","operationId":"start_assessment_api_bench_profile__token__assessments_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartAssessmentBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bench-profile/{token}/roles":{"post":{"tags":["bench-profile"],"summary":"Add Role","description":"Apply to another role from the profile: role interest upsert + start\nthat role's package through the same start path. The interest is\nrecorded even when the package can't start right now (`blocked` says\nwhy) — the response is 202 either way; 422 for an unknown role.","operationId":"add_role_api_bench_profile__token__roles_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddRoleBody"}}}},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/bench-profile/{token}/interview-retake":{"post":{"tags":["bench-profile"],"summary":"Interview Retake","description":"Retake the AI interview — only after a fail, only once the 90-day\ncooldown has passed, never while one is active. A pass is final.","operationId":"interview_retake_api_bench_profile__token__interview_retake_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidate-accounts/roles":{"get":{"tags":["candidate-accounts"],"summary":"Signup Roles","description":"The roles a newcomer can pick as their target on the signup form.\n\nUnauthenticated by necessity: the person asking has no account yet, and\nthe answer is the same list `/jobs` already publishes on the open\ninternet. Nothing candidate-specific is in the response.\n\nBehind `_gate()` like the rest of this router, so the surface appears\nand disappears as one feature. A failure returns an EMPTY list rather\nthan a 500: the signup form degrades to \"we could not load the roles,\njoin anyway and pick later\", which is strictly better than blocking a\nsignup on a dropdown.","operationId":"signup_roles_api_candidate_accounts_roles_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/candidate-accounts/request-code":{"post":{"tags":["candidate-accounts"],"summary":"Request Code","description":"Email a 6-digit code. Always 202, never an enumeration oracle.\n\nThe IP limit here is belt-and-braces on top of the DB-backed per-email\nlimit in the service (which is the one that survives multiple replicas).\n429 is the ONE non-202 outcome, because silently dropping a code the\ncandidate is waiting for is worse than telling them to wait.","operationId":"request_code_api_candidate_accounts_request_code_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestCodeBody"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidate-accounts/verify":{"post":{"tags":["candidate-accounts"],"summary":"Verify Code","description":"Exchange the code for a session.\n\nThe token is returned in the BODY, not set as a cookie here: the cookie\nbelongs to the frontend's own host (talent./developers. are host-only,\ndeliberately) and crm-api is on a different origin, so a Set-Cookie from\nhere would be a third-party cookie that modern browsers drop.","operationId":"verify_code_api_candidate_accounts_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyCodeBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidate-accounts/me":{"get":{"tags":["candidate-accounts"],"summary":"Me","description":"Identity strip. Cheap enough for the nav to call on every page.","operationId":"me_api_candidate_accounts_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/candidate/home":{"get":{"tags":["candidate-accounts"],"summary":"Home","description":"Everything the home, /skills, /badge and /visibility render.","operationId":"home_api_candidate_home_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/candidate/card-preview":{"get":{"tags":["candidate-accounts"],"summary":"Card Preview","description":"What a client sees when your card comes up, plus what is thinning it.\n\nDeliberately NOT folded into `/api/candidate/home`: the home is fetched\nby all five talent routes and only one of them renders a card. It also\nlets `/visibility` own the three states a data surface must have\n(loading, error, empty) for this block instead of inheriting the\nhome's.\n\nThe magic-link twin is `GET /api/bench-profile/{token}/card-preview`.\nBoth call `card_preview_service.get_card_preview` and do nothing else.","operationId":"card_preview_api_candidate_card_preview_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/candidate/profile":{"patch":{"tags":["candidate-accounts"],"summary":"Update Profile","description":"/settings saves.\n\nRoutes through `bench_profile_service.update_profile` — the same\nallow-list, the same validation, the same availability-confirmation\nstamp the magic link gets. A session must not be able to edit anything a\ntoken cannot; if it could, the two surfaces would need two audits.","operationId":"update_profile_api_candidate_profile_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdateBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidate/assessments":{"get":{"tags":["candidate-accounts"],"summary":"List Assessments","description":"The whole catalogue, session-authed: every startable package with\nTHIS candidate's state per package.\n\nThe magic-link twin is `GET /api/bench-profile/{token}/assessments`.\nBoth call `self_serve_service.catalog` and `serialize_catalog` and do\nnothing else, so a passed package is un-retakeable, a failed one inside\nthe 90-day cooldown carries its retry date, and the one-at-a-time lock\nreads the same, whichever door the candidate came through. There is\ndeliberately no second query and no second opinion about eligibility\nhere: `test_e2e_candidate_catalogue.py` asserts the two payloads are\nequal for the same candidate, and that equivalence is the whole point of\nthe endpoint existing rather than the home payload growing a 44-item\narray that four other pages would carry for nothing.\n\nRate limit is the token twin's (60/hour), keyed by session rather than\nby token: browsing a catalogue is cheap and a candidate comparing\npackages should not hit a wall.","operationId":"list_assessments_api_candidate_assessments_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["candidate-accounts"],"summary":"Start Assessment","description":"One click on \"start\" from the home's next-best-action block.\n\nSame core as the magic link's start endpoint, including the eligibility\ngate and the email-first rollback, so the two doors cannot disagree about\nwhat may be started. Concurrent assessments ARE allowed (a candidate is\nfree to pivot from frontend to backend without abandoning anything); what\nboth doors share is the in-flight budget, rule 6 of the eligibility\nmodule, which 409s with reason='at_cap'.","operationId":"start_assessment_api_candidate_assessments_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartAssessmentBody"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/verified/{public_badge_id}":{"get":{"tags":["verified"],"summary":"Get Verified","description":"Public badge payload. 404 for unknown/malformed ids.","operationId":"get_verified_api_verified__public_badge_id__get","parameters":[{"name":"public_badge_id","in":"path","required":true,"schema":{"type":"string","title":"Public Badge Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/verified/{public_badge_id}/badge.svg":{"get":{"tags":["verified"],"summary":"Get Badge Svg","description":"The badge as an SVG — same data as the JSON, rendered for sharing.","operationId":"get_badge_svg_api_verified__public_badge_id__badge_svg_get","parameters":[{"name":"public_badge_id","in":"path","required":true,"schema":{"type":"string","title":"Public Badge Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/verified/{public_badge_id}/badge.png":{"get":{"tags":["verified"],"summary":"Get Badge Png","description":"Raster badge — this is what `og:image` points at (LinkedIn, Slack and\nTwitter all refuse SVG for unfurls).\n\nThe render is memoized per payload and runs off the event loop; the SVG\npath (three orders of magnitude cheaper) needs neither.","operationId":"get_badge_png_api_verified__public_badge_id__badge_png_get","parameters":[{"name":"public_badge_id","in":"path","required":true,"schema":{"type":"string","title":"Public Badge Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/verified/{public_badge_id}/linkedin":{"get":{"tags":["verified"],"summary":"Add To Linkedin","description":"Tracked hop behind every \"Add to LinkedIn\" button (B4 FR-7).\n\nSame 404 path as the JSON endpoint (no enumeration oracle). An archived\nbadge still redirects — the engineer may already have the cert, and the\nverify page is what reports it as no longer valid. The click is counted\nfire-and-forget; it never delays or blocks the 302.\n\n`site` is the public origin the /verified page was served on (talent vs\ndevelopers); only allow-listed origins are honoured.","operationId":"add_to_linkedin_api_verified__public_badge_id__linkedin_get","parameters":[{"name":"public_badge_id","in":"path","required":true,"schema":{"type":"string","title":"Public Badge Id"}},{"name":"src","in":"query","required":false,"schema":{"type":"string","default":"","title":"Src"}},{"name":"site","in":"query","required":false,"schema":{"type":"string","default":"","title":"Site"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/bench-availability":{"get":{"tags":["shortlist"],"summary":"Bench Availability","description":"Return the bench-tier classification for a (skills, seniority) slice.\n\nPublic endpoint — the /qualify confirmation page hits this server-side\nimmediately after submit to choose between the fast / standard /\nsourcing email + page templates.\n\nCached for 5 minutes per (skills_normalized, seniority) — bench\nvolume rarely changes between two leads filling the form within a\nshort window.","operationId":"bench_availability_api_shortlist_bench_availability_get","parameters":[{"name":"stack","in":"query","required":true,"schema":{"type":"string","maxLength":500,"description":"Comma-separated skills, e.g. 'python,aws,fastapi'","title":"Stack"},"description":"Comma-separated skills, e.g. 'python,aws,fastapi'"},{"name":"seniority","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"description":"One of: mid, senior, staff, lead. Anything else = 'any'.","title":"Seniority"},"description":"One of: mid, senior, staff, lead. Anything else = 'any'."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Bench Availability Api Shortlist Bench Availability Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{token}":{"get":{"tags":["shortlist"],"summary":"Lead Facing Shortlist","description":"Public — return the published candidate cards for a lead.\n\nThe lead's identity is the token itself. Empty publishings → 200 with\nan empty `candidates` array (the page can render an empty state and\ntell the lead \"your shortlist is being prepared\").","operationId":"lead_facing_shortlist_api_shortlist_lead__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Lead Facing Shortlist Api Shortlist Lead  Token  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{token}/chat-context":{"get":{"tags":["shortlist"],"summary":"Lead Facing Chat Context","description":"Public (token-gated) — blind grounding payload for the Sol shortlist\nconcierge (Sol v2 §16).\n\nCalled service-to-service by chat-api when a shortlist chat session is\ncreated. Blind-by-construction: the serializer is an allowlist with a\nruntime identifier scan — candidate names and employer names never\nappear in this response. See chat_context_service for the contract.","operationId":"lead_facing_chat_context_api_shortlist_lead__token__chat_context_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"session_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Lead Facing Chat Context Api Shortlist Lead  Token  Chat Context Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{token}/candidate/{candidate_id}":{"get":{"tags":["shortlist"],"summary":"Lead Facing Candidate Detail","description":"Return the rendered HTML one-pager for a candidate, gated by token.\n\nAlso records a candidate_view row — opening the modal IS the signal\nwe want to capture. We don't dedup at the row level; downstream\naggregation in the dashboard does the rollup.","operationId":"lead_facing_candidate_detail_api_shortlist_lead__token__candidate__candidate_id__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Lead Facing Candidate Detail Api Shortlist Lead  Token  Candidate  Candidate Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{token}/track-view":{"post":{"tags":["shortlist"],"summary":"Lead Facing Track View","description":"Beacon endpoint — page hits this on card open even if the modal\nfetch already counted (some clients pre-fetch the detail). Idempotent\nin the sense that a few extra rows don't hurt analytics.","operationId":"lead_facing_track_view_api_shortlist_lead__token__track_view_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_TrackViewBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Lead Facing Track View Api Shortlist Lead  Token  Track View Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{token}/opened":{"post":{"tags":["shortlist"],"summary":"Lead Facing Opened","description":"Beacon: the page has been on screen for a moment (first-open alert).\n\nThe page calls this once per browser session, only after the shortlist\nhas rendered AND the tab has been visible for ~1.5 s. Mail-security\nscanners that prefetch links mostly never execute that far; the user\nagent filter catches the ones that do. Card opens used to be the only\nview signal, so a buyer who read the page and left was invisible.","operationId":"lead_facing_opened_api_shortlist_lead__token__opened_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Lead Facing Opened Api Shortlist Lead  Token  Opened Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{token}/feedback":{"post":{"tags":["shortlist"],"summary":"Lead Facing Card Feedback","description":"Record a 👍/👎 (+ reason chips) on one shortlist card — Epic 5.4.\n\nUpsert semantics: the buyer owns one opinion per card, and changing\ntheir mind must replace the old vote rather than append to it, or a\nstale 👎 keeps driving the refresh loop after they retracted it.\n\nRate limit is generous on purpose. A real buyer tapping through a\n20-card shortlist and correcting themselves twice is well inside it;\nit exists to stop a script, not a person.","operationId":"lead_facing_card_feedback_api_shortlist_lead__token__feedback_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_FeedbackBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Lead Facing Card Feedback Api Shortlist Lead  Token  Feedback Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{token}/share":{"post":{"tags":["shortlist"],"summary":"Lead Facing Share","description":"Share this shortlist with colleagues — Epic 5.3.\n\nCreates a tracked CHILD link per colleague and emails it. Each child\ninherits the parent's expiry, resolves to the same lead, and serves the\nSAME blind payload: sharing changes who we can attribute a view to,\nnever what a viewer is allowed to see. No candidate identity reaches\nany pre-MSA surface, shared or not.\n\nSharing a share is refused (the service only accepts a parent token) —\na chain would make attribution meaningless and let a link escape the\nbuyer's own circle without their knowledge.\n\nONE TOKEN PER PERSON, always. That is what makes the second-viewer\nalert mean something: a distinct stakeholder opening the shortlist is\namong the strongest buying signals there is, and it is only visible if\nthe CTO and the VP Eng hold different links.\n\nRecipients are processed INDEPENDENTLY. One opted-out address, or one\ntypo, must not silently discard the other two invitations the buyer\njust sent — the caller gets a per-address result and can say so.\n\nThe rate limit is tight because this endpoint mails people who never\ngave us their address; `MAX_SHARE_RECIPIENTS` bounds the fan-out\nwithin a single request for the same reason.","operationId":"lead_facing_share_api_shortlist_lead__token__share_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_ShareBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Lead Facing Share Api Shortlist Lead  Token  Share Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{token}/request-intro-by-position":{"post":{"tags":["shortlist"],"summary":"Lead Facing Request Intro By Position","description":"Sol concierge intro request — position resolved to candidate_id\nserver-side so chat-api (and the model) never handle candidate ids.\n\nDelegates to the canonical request-intro flow once resolved.","operationId":"lead_facing_request_intro_by_position_api_shortlist_lead__token__request_intro_by_position_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_RequestIntroByPositionBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{token}/chat-question":{"post":{"tags":["shortlist"],"summary":"Lead Facing Chat Question","description":"Sol's notify_team escape hatch — a client question the blind\ncontext can't answer. Slack ping so Roberto answers within the 4h\npromise Sol just made.\n\nThe buyer also gets a short confirmation email; its tracked\nemail_events row (template=chat_question_confirmation, question in\npayload_vars) doubles as the durable record of the question.","operationId":"lead_facing_chat_question_api_shortlist_lead__token__chat_question_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_ChatQuestionBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Lead Facing Chat Question Api Shortlist Lead  Token  Chat Question Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{token}/request-intro":{"post":{"tags":["shortlist"],"summary":"Lead Facing Request Intro","description":"Lead clicked \"Request intro\" on a candidate card.\n\nEpic 1.1 (V1.5): records an intro_requests row (SLA timer included),\nauto-advances the lead's kanban stage, queues the Slack ping +\ninternal fallback email, and sends the buyer a confirmation email\nwith the Cal.com walkthrough CTA.","operationId":"lead_facing_request_intro_api_shortlist_lead__token__request_intro_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_RequestIntroBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{lead_id}/publish":{"post":{"tags":["shortlist"],"summary":"Publish Shortlist For Lead","description":"Publish a hand-picked candidate set to a lead.\n\nIdempotent at the lead level — re-publishing replaces the prior\nslate (prior rows soft-revoked, new rows inserted). Issues / refreshes\nthe lead's magic-link token in the same transaction so the email\nsent below points at a live link.","operationId":"publish_shortlist_for_lead_api_shortlist_lead__lead_id__publish_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_PublishBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Publish Shortlist For Lead Api Shortlist Lead  Lead Id  Publish Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{lead_id}/publishings/{publishing_id}":{"delete":{"tags":["shortlist"],"summary":"Revoke Publishing Endpoint","description":"Pull a single candidate from a lead's shortlist (e.g. they became\nunavailable). The lead's page renders the slot as \"no longer\navailable\" rather than removing it.","operationId":"revoke_publishing_endpoint_api_shortlist_lead__lead_id__publishings__publishing_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}},{"name":"publishing_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Publishing Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Revoke Publishing Endpoint Api Shortlist Lead  Lead Id  Publishings  Publishing Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/leads/{lead_id}/summary":{"get":{"tags":["shortlist"],"summary":"Get Lead Summary For Publish","description":"Tiny recruiter-only endpoint that backs the publish UI's header.\n\nReturns just the fields the dashboard needs to render the page banner:\nname, email, company, seniority, skills_summary. No activity, no\npublishings — those have their own endpoints.","operationId":"get_lead_summary_for_publish_api_shortlist_leads__lead_id__summary_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Lead Summary For Publish Api Shortlist Leads  Lead Id  Summary Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/lead/{lead_id}/activity":{"get":{"tags":["shortlist"],"summary":"Lead Activity Summary","description":"Per-candidate view counts + recency for the dashboard activity pane.","operationId":"lead_activity_summary_api_shortlist_lead__lead_id__activity_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Lead Activity Summary Api Shortlist Lead  Lead Id  Activity Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/shortlist/leads/{lead_id}/recommended-candidates":{"get":{"tags":["shortlist"],"summary":"Get Recommended Candidates For Lead","description":"C3 — return Bench candidates ranked for this lead.\n\nTwo ranked lists:\n  - ``recommended``: candidates that PASS the same strict filter\n    ``bench_availability_service._count_vetted_matching`` uses (so what\n    the recruiter pre-publishes is guaranteed consistent with the tier\n    the lead was told in their confirmation email). Within the matched\n    set, ranked by ``NeonService._score_candidate``.\n  - ``other_bench``: Bench candidates that do NOT pass the strict filter,\n    ordered by ``overall_score``. Used as the \"Other Bench candidates\"\n    fallback section for Option B (fill-from-other-bench when strict\n    matches are sparse) and for manual sourcing-tier picks.\n\nAlso returns the ``tier`` and ``strict_match_count`` so the dashboard\ncan render the right empty-state hints — same source of truth that\ndrives the lead's confirmation email.\n\nC3.x.5: also returns ``current_publishings`` (active publishing IDs +\ncandidate IDs for what's already live on the lead's magic-link page)\nand ``magic_link_url`` (read-only \"view as client\" deep link). Lets\nthe dashboard pre-check the auto-published candidates and surface a\nbanner so the recruiter knows the lead already saw a shortlist.","operationId":"get_recommended_candidates_for_lead_api_shortlist_leads__lead_id__recommended_candidates_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"lead_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Lead Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"default":25,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Recommended Candidates For Lead Api Shortlist Leads  Lead Id  Recommended Candidates Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/redact-companies":{"post":{"tags":["shortlist"],"summary":"Redact Companies","description":"Run (or refresh) Claude-generated company redactions for blind PDFs.\n\nCache-first by default. Pass `force=true` to invalidate and re-run.","operationId":"redact_companies_api_candidates__candidate_id__redact_companies_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactCompaniesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactCompaniesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/redactions":{"get":{"tags":["shortlist"],"summary":"Get Redactions","description":"Fetch cached redactions WITHOUT triggering a Claude call.","operationId":"get_redactions_api_candidates__candidate_id__redactions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RedactCompaniesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/send-shortlist":{"post":{"tags":["shortlist"],"summary":"Send Shortlist","description":"Render PDFs for selected candidates → email to client → audit-log each one.","operationId":"send_shortlist_api_projects__project_id__send_shortlist_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendShortlistRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendShortlistResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/projects/{project_id}/access-log":{"get":{"tags":["shortlist"],"summary":"Project Access Log","operationId":"project_access_log_api_projects__project_id__access_log_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"project_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Project Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AccessLogEntry"},"title":"Response Project Access Log Api Projects  Project Id  Access Log Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/audit/trace/{track_id}":{"get":{"tags":["shortlist"],"summary":"Trace Track Id","description":"Forensic lookup: 'I saw watermark XYZ on a leaked PDF'.","operationId":"trace_track_id_api_audit_trace__track_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"track_id","in":"path","required":true,"schema":{"type":"string","title":"Track Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessLogEntry"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidate-referrals":{"post":{"tags":["candidate-referrals"],"summary":"Submit Candidate Referral","description":"Submit a new candidate referral\n\nCandidates and client users can submit referrals.\nAutomatically calculates quality score and checks for duplicates.","operationId":"submit_candidate_referral_api_candidate_referrals_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateReferralCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateReferralResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["candidate-referrals"],"summary":"List Candidate Referrals","description":"List candidate referrals\n\nFounders see all referrals.\nOther users see only their own referrals.","operationId":"list_candidate_referrals_api_candidate_referrals_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"referrer_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by referrer type","title":"Referrer Type"},"description":"Filter by referrer type"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Per Page"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateReferralListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidate-referrals/my-referrals":{"get":{"tags":["candidate-referrals"],"summary":"Get My Referrals","description":"Get current user's referral dashboard","operationId":"get_my_referrals_api_candidate_referrals_my_referrals_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MyReferralsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/candidate-referrals/analytics":{"get":{"tags":["candidate-referrals"],"summary":"Get Referral Analytics","description":"Get referral program analytics (founder only)","operationId":"get_referral_analytics_api_candidate_referrals_analytics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReferralAnalytics"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/candidate-referrals/{referral_id}":{"get":{"tags":["candidate-referrals"],"summary":"Get Candidate Referral","description":"Get single candidate referral by ID","operationId":"get_candidate_referral_api_candidate_referrals__referral_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"referral_id","in":"path","required":true,"schema":{"type":"string","title":"Referral Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateReferralResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidate-referrals/{referral_id}/status":{"patch":{"tags":["candidate-referrals"],"summary":"Update Referral Status","description":"Update candidate referral status (founder or recruiter)","operationId":"update_referral_status_api_candidate_referrals__referral_id__status_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"referral_id","in":"path","required":true,"schema":{"type":"string","title":"Referral Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateReferralUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CandidateReferralResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidate-referrals/{referral_id}/convert":{"post":{"tags":["candidate-referrals"],"summary":"Convert Referral To Candidate","description":"Convert referral to candidate record (founder only)","operationId":"convert_referral_to_candidate_api_candidate_referrals__referral_id__convert_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"referral_id","in":"path","required":true,"schema":{"type":"string","title":"Referral Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConvertReferralRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConvertReferralResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidate-referrals/{referral_id}/history":{"get":{"tags":["candidate-referrals"],"summary":"Get Candidate Referral History","description":"Get status change history for a candidate referral","operationId":"get_candidate_referral_history_api_candidate_referrals__referral_id__history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"referral_id","in":"path","required":true,"schema":{"type":"string","title":"Referral Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/client-referrals":{"post":{"tags":["client-referrals"],"summary":"Submit Client Referral","description":"Submit a new client/company referral\n\nCandidates and client users can submit referrals.","operationId":"submit_client_referral_api_client_referrals_post","security":[{"HTTPBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientReferralCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientReferralResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["client-referrals"],"summary":"List Client Referrals","description":"List client referrals\n\nFounders see all, users see only their own.","operationId":"list_client_referrals_api_client_referrals_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"referrer_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Type"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"per_page","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Per Page"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientReferralListResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/client-referrals/my-referrals":{"get":{"tags":["client-referrals"],"summary":"Get My Client Referrals","description":"Get current user's client referral dashboard","operationId":"get_my_client_referrals_api_client_referrals_my_referrals_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MyClientReferralsResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/client-referrals/leaderboard":{"get":{"tags":["client-referrals"],"summary":"Get Referral Leaderboard","description":"Get referral leaderboard (all users can view)","operationId":"get_referral_leaderboard_api_client_referrals_leaderboard_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","description":"Period: all_time, this_quarter","default":"all_time","title":"Period"},"description":"Period: all_time, this_quarter"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientReferralLeaderboard"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/client-referrals/stats":{"get":{"tags":["client-referrals"],"summary":"Get Client Referral Stats","description":"Get overall program stats (founder only)","operationId":"get_client_referral_stats_api_client_referrals_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientReferralStats"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/client-referrals/{referral_id}":{"get":{"tags":["client-referrals"],"summary":"Get Client Referral","description":"Get single client referral","operationId":"get_client_referral_api_client_referrals__referral_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"referral_id","in":"path","required":true,"schema":{"type":"string","title":"Referral Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientReferralResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/client-referrals/{referral_id}/status":{"patch":{"tags":["client-referrals"],"summary":"Update Client Referral Status","description":"Update client referral status (founder or recruiter).\n\nWhen status changes to \"Signed\" and the referral has a converted_company_id,\nthe reward is automatically calculated and applied as a Stripe customer\nbalance credit (auto-deducted from the next invoice).","operationId":"update_client_referral_status_api_client_referrals__referral_id__status_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"referral_id","in":"path","required":true,"schema":{"type":"string","title":"Referral Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientReferralUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientReferralResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/client-referrals/{referral_id}/convert":{"post":{"tags":["client-referrals"],"summary":"Convert Referral To Company","description":"Convert referral to company (founder only)","operationId":"convert_referral_to_company_api_client_referrals__referral_id__convert_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"referral_id","in":"path","required":true,"schema":{"type":"string","title":"Referral Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConvertToCompanyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConvertToCompanyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/client-referrals/{referral_id}/reward":{"patch":{"tags":["client-referrals"],"summary":"Process Reward Payout","description":"Process reward payout (founder only)","operationId":"process_reward_payout_api_client_referrals__referral_id__reward_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"referral_id","in":"path","required":true,"schema":{"type":"string","title":"Referral Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardPayoutRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RewardPayoutResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/client-referrals/{referral_id}/tranches":{"get":{"tags":["client-referrals"],"summary":"Get Client Referral Tranches","description":"v2 reward tranches for one client referral (founder only).","operationId":"get_client_referral_tranches_api_client_referrals__referral_id__tranches_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"referral_id","in":"path","required":true,"schema":{"type":"string","title":"Referral Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/client-referrals/{referral_id}/tranches/{tranche}/mark-paid":{"post":{"tags":["client-referrals"],"summary":"Mark Client Referral Tranche Paid","description":"Record that an Approved tranche was paid MANUALLY. Moves no money.","operationId":"mark_client_referral_tranche_paid_api_client_referrals__referral_id__tranches__tranche__mark_paid_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"referral_id","in":"path","required":true,"schema":{"type":"string","title":"Referral Id"}},{"name":"tranche","in":"path","required":true,"schema":{"type":"string","title":"Tranche"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/_MarkPaidBody"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/client-referrals/{referral_id}/history":{"get":{"tags":["client-referrals"],"summary":"Get Client Referral History","description":"Get status change history for a client referral","operationId":"get_client_referral_history_api_client_referrals__referral_id__history_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"referral_id","in":"path","required":true,"schema":{"type":"string","title":"Referral Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/english/backfill/status":{"get":{"tags":["english-signal"],"summary":"Backfill Status","operationId":"backfill_status_api_english_backfill_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/english/backfill":{"post":{"tags":["english-signal"],"summary":"Start Backfill","operationId":"start_backfill_api_english_backfill_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackfillRequest"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/english/label-queue":{"get":{"tags":["english-signal"],"summary":"Get Label Queue","operationId":"get_label_queue_api_english_label_queue_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/english/labels":{"post":{"tags":["english-signal"],"summary":"Post Label","operationId":"post_label_api_english_labels_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabelIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/english/agreement":{"get":{"tags":["english-signal"],"summary":"Get Agreement","operationId":"get_agreement_api_english_agreement_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/ml/training-manifest":{"get":{"tags":["ml-training"],"summary":"Training Manifest","operationId":"training_manifest_api_ml_training_manifest_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/company-memory/sweep":{"post":{"tags":["Company Memory"],"summary":"Company Memory Sweep","description":"15-min cron: Sol session capture, extraction catch-up, embeddings.","operationId":"company_memory_sweep_api_company_memory_sweep_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Company Memory Sweep Api Company Memory Sweep Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/company-memory":{"get":{"tags":["Company Memory"],"summary":"Admin List Domains","operationId":"admin_list_domains_api_admin_company_memory_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Q"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin List Domains Api Admin Company Memory Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/company-memory/kpis":{"get":{"tags":["Company Memory"],"summary":"Admin Kpis","operationId":"admin_kpis_api_admin_company_memory_kpis_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Kpis Api Admin Company Memory Kpis Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/company-memory/facts/{fact_id}":{"patch":{"tags":["Company Memory"],"summary":"Admin Patch Fact","operationId":"admin_patch_fact_api_admin_company_memory_facts__fact_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"fact_id","in":"path","required":true,"schema":{"type":"string","title":"Fact Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FactPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Patch Fact Api Admin Company Memory Facts  Fact Id  Patch"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Company Memory"],"summary":"Admin Delete Fact","operationId":"admin_delete_fact_api_admin_company_memory_facts__fact_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"fact_id","in":"path","required":true,"schema":{"type":"string","title":"Fact Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Delete Fact Api Admin Company Memory Facts  Fact Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/company-memory/{domain}":{"get":{"tags":["Company Memory"],"summary":"Admin Domain View","operationId":"admin_domain_view_api_admin_company_memory__domain__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Domain View Api Admin Company Memory  Domain  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Company Memory"],"summary":"Admin Purge Domain","description":"Whole-company delete. ``?confirm=<domain>`` must repeat the domain:\nthis purges facts AND evidence and cannot be undone.","operationId":"admin_purge_domain_api_admin_company_memory__domain__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"confirm","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Confirm"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Purge Domain Api Admin Company Memory  Domain  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/company-memory/{domain}/evidence":{"get":{"tags":["Company Memory"],"summary":"Admin Domain Evidence","operationId":"admin_domain_evidence_api_admin_company_memory__domain__evidence_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Cursor"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Domain Evidence Api Admin Company Memory  Domain  Evidence Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/company-memory/{domain}/notes":{"post":{"tags":["Company Memory"],"summary":"Admin Add Note","operationId":"admin_add_note_api_admin_company_memory__domain__notes_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoteIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Add Note Api Admin Company Memory  Domain  Notes Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/company-memory/{domain}/brief":{"get":{"tags":["Company Memory"],"summary":"Admin Brief","operationId":"admin_brief_api_admin_company_memory__domain__brief_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Brief Api Admin Company Memory  Domain  Brief Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/company-memory/{domain}/search":{"get":{"tags":["Company Memory"],"summary":"Admin Search","description":"Search everything this company told us (keyword, + vectors when on).","operationId":"admin_search_api_admin_company_memory__domain__search_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"q","in":"query","required":false,"schema":{"type":"string","default":"","title":"Q"}},{"name":"k","in":"query","required":false,"schema":{"type":"integer","default":8,"title":"K"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Admin Search Api Admin Company Memory  Domain  Search Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/identity/shortlist-proof":{"post":{"tags":["Company Memory (internal)"],"summary":"Shortlist Proof","description":"A shortlist link we emailed IS proof for the lead's company domain\n(a forwarded link grants the colleague the same view: PRD section 7).","operationId":"shortlist_proof_api_internal_identity_shortlist_proof_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShortlistProofIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Shortlist Proof Api Internal Identity Shortlist Proof Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/identity/code/send":{"post":{"tags":["Company Memory (internal)"],"summary":"Code Send","description":"Email a 6-digit code (corporate inboxes only; 3/hour/email, 10/hour/IP).","operationId":"code_send_api_internal_identity_code_send_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeSendIn"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Code Send Api Internal Identity Code Send Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/identity/code/check":{"post":{"tags":["Company Memory (internal)"],"summary":"Code Check","operationId":"code_check_api_internal_identity_code_check_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeCheckIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Code Check Api Internal Identity Code Check Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/company-memory/{domain}/exists":{"get":{"tags":["Company Memory (internal)"],"summary":"Memory Exists","description":"Whether there is anything Sol could say back (decides if Sol offers\nthe 6-digit code at all). Proxy token only; reveals no content.","operationId":"memory_exists_api_internal_company_memory__domain__exists_get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Memory Exists Api Internal Company Memory  Domain  Exists Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/company-memory/{domain}":{"get":{"tags":["Company Memory (internal)"],"summary":"Memory Read","description":"Sol's prompt view: active, verified, confident, Sol-visible facts only.\nNever evidence, never budget.","operationId":"memory_read_api_internal_company_memory__domain__get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"x-memory-proof","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Memory-Proof"}},{"name":"x-session-id","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Session-Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Memory Read Api Internal Company Memory  Domain  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Company Memory (internal)"],"summary":"Memory Delete All","description":"Visitor 'forget everything about us': facts + evidence purged,\ntombstone kept (PRD section 7).","operationId":"memory_delete_all_api_internal_company_memory__domain__delete","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"x-memory-proof","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Memory-Proof"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Memory Delete All Api Internal Company Memory  Domain  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/company-memory/{domain}/correction":{"post":{"tags":["Company Memory (internal)"],"summary":"Memory Correction","description":"A verified visitor's correction: highest precedence (PRD 6.4).","operationId":"memory_correction_api_internal_company_memory__domain__correction_post","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"x-memory-proof","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Memory-Proof"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CorrectionIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Memory Correction Api Internal Company Memory  Domain  Correction Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/company-memory/{domain}/export":{"get":{"tags":["Company Memory (internal)"],"summary":"Memory Export","operationId":"memory_export_api_internal_company_memory__domain__export_get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"x-memory-proof","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Memory-Proof"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Memory Export Api Internal Company Memory  Domain  Export Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/company-memory/{domain}/facts/{fact_id}":{"delete":{"tags":["Company Memory (internal)"],"summary":"Memory Delete Fact","operationId":"memory_delete_fact_api_internal_company_memory__domain__facts__fact_id__delete","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"fact_id","in":"path","required":true,"schema":{"type":"string","title":"Fact Id"}},{"name":"x-memory-proof","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Memory-Proof"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Memory Delete Fact Api Internal Company Memory  Domain  Facts  Fact Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/company-memory/session-proof":{"post":{"tags":["Company Memory (internal)"],"summary":"Memory Session Proof","description":"chat-api reports that a Sol session holds a valid proof. The sweep\nthen stores that session's evidence as VERIFIED (facts go active, not\npending). Evidence already captured for the session is upgraded too.\nIdempotent per (session, domain).","operationId":"memory_session_proof_api_internal_company_memory_session_proof_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionProofIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Memory Session Proof Api Internal Company Memory Session Proof Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/internal/company-memory/{domain}/search":{"post":{"tags":["Company Memory (internal)"],"summary":"Memory Search","description":"At most 3 PII-stripped snippets from VERIFIED evidence only (text a\nstranger typed into an unverified session is never said back).","operationId":"memory_search_api_internal_company_memory__domain__search_post","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"x-memory-proof","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Memory-Proof"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Memory Search Api Internal Company Memory  Domain  Search Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/auth/code":{"post":{"tags":["Sol App (internal)"],"summary":"Send Code","operationId":"send_code_api_sol_app_auth_code_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CodeIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/auth/verify":{"post":{"tags":["Sol App (internal)"],"summary":"Verify Code","operationId":"verify_code_api_sol_app_auth_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/auth/linkedin/start":{"post":{"tags":["Sol App (internal)"],"summary":"Linkedin Start","operationId":"linkedin_start_api_sol_app_auth_linkedin_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkedInStartIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/auth/google/start":{"post":{"tags":["Sol App (internal)"],"summary":"Google Start","operationId":"google_start_api_sol_app_auth_google_start_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkedInStartIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/auth/linkedin/callback":{"post":{"tags":["Sol App (internal)"],"summary":"Linkedin Callback","description":"Consumes the state (once), exchanges the code, validates the\nid_token, links or creates the account and opens a session. Same\nresponse shape as /auth/verify plus `linked` and `return_to`.","operationId":"linkedin_callback_api_sol_app_auth_linkedin_callback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkedInCallbackIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/auth/google/callback":{"post":{"tags":["Sol App (internal)"],"summary":"Google Callback","description":"Sign in with Google, company (Workspace) accounts only: the verified\nwork email signs the buyer in AND proves `corporate`. Same response\nshape as the LinkedIn callback (`linked` = newly verified).","operationId":"google_callback_api_sol_app_auth_google_callback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LinkedInCallbackIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/auth/claim-anon":{"post":{"tags":["Sol App (internal)"],"summary":"Claim Anon After Oauth","description":"Moves this browser's anonymous chats to the signed-in account after an\nOAuth round trip. Internal (proxy token): the only caller is apps/sol's\nPOST /api/auth/claim, which is same-origin, requires a session and sends\nTHAT session's user id, never one from the browser. The anon id no\nlonger travels in the start URL, where a crafted link could plant\nsomeone else's chats in the victim's history (security review L1).","operationId":"claim_anon_after_oauth_api_sol_app_auth_claim_anon_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClaimAnonIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/auth/session/validate":{"post":{"tags":["Sol App (internal)"],"summary":"Validate Session","operationId":"validate_session_api_sol_app_auth_session_validate_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/auth/signout":{"post":{"tags":["Sol App (internal)"],"summary":"Sign Out","operationId":"sign_out_api_sol_app_auth_signout_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/conversations/{conversation_id}/turns":{"post":{"tags":["Sol App (internal)"],"summary":"Append Turn","operationId":"append_turn_api_sol_app_conversations__conversation_id__turns_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TurnIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/conversations/{conversation_id}":{"get":{"tags":["Sol App (internal)"],"summary":"Get Conversation","operationId":"get_conversation_api_sol_app_conversations__conversation_id__get","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"user_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"}},{"name":"anon_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Anon Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Sol App (internal)"],"summary":"Patch Conversation","operationId":"patch_conversation_api_sol_app_conversations__conversation_id__patch","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Sol App (internal)"],"summary":"Delete Conversation","operationId":"delete_conversation_api_sol_app_conversations__conversation_id__delete","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"user_id","in":"query","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/users/{user_id}/conversations":{"get":{"tags":["Sol App (internal)"],"summary":"List Conversations","operationId":"list_conversations_api_sol_app_users__user_id__conversations_get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Cursor"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/conversations/{conversation_id}/share":{"post":{"tags":["Sol App (internal)"],"summary":"Create Share","operationId":"create_share_api_sol_app_conversations__conversation_id__share_post","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnerIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Sol App (internal)"],"summary":"Revoke Share","operationId":"revoke_share_api_sol_app_conversations__conversation_id__share_delete","parameters":[{"name":"conversation_id","in":"path","required":true,"schema":{"type":"string","title":"Conversation Id"}},{"name":"user_id","in":"query","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/share/{token}":{"get":{"tags":["Sol App (internal)"],"summary":"Read Share","operationId":"read_share_api_sol_app_share__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/users/{user_id}/saved-engineers":{"get":{"tags":["Sol App (internal)"],"summary":"List Saved","operationId":"list_saved_api_sol_app_users__user_id__saved_engineers_get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Sol App (internal)"],"summary":"Save Engineer","operationId":"save_engineer_api_sol_app_users__user_id__saved_engineers_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SaveIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/users/{user_id}/saved-engineers/{ref}":{"delete":{"tags":["Sol App (internal)"],"summary":"Unsave Engineer","operationId":"unsave_engineer_api_sol_app_users__user_id__saved_engineers__ref__delete","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"ref","in":"path","required":true,"schema":{"type":"string","title":"Ref"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/users/{user_id}/shortlist-request":{"post":{"tags":["Sol App (internal)"],"summary":"Shortlist From Saved","description":"Turns the saved list into a shortlist request (plan §5.6).\n\nThe refs are resolved to candidates HERE (and only here) against the live\npublic bench; engineers no longer on it are excluded and reported as\n`unavailable_refs` (never why). The request goes through the same\n/api/forms/shortlist-request handler every other surface uses, with the\nsigned-in user's verified email. The response is the blind confirmation\nonly: no names, no candidate ids, no lead id.","operationId":"shortlist_from_saved_api_sol_app_users__user_id__shortlist_request_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShortlistIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/extract":{"post":{"tags":["Sol App (internal)"],"summary":"Extract Pdf","description":"Raw PDF bytes in → ``{text, truncated, pages}`` (review round 2).\n\nCalled by chat-api POST /chat/app/extract (which rate-limits per IP).\nThe body is capped while it is READ (Content-Length is optional), the\nbytes live for this request only, and only sizes are logged.","operationId":"extract_pdf_api_sol_app_extract_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/sol-app/retention":{"post":{"tags":["Sol App (internal)"],"summary":"Retention","operationId":"retention_api_sol_app_retention_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/metrics":{"get":{"tags":["Sol App (internal)"],"summary":"Metrics","operationId":"metrics_api_sol_app_metrics_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/users/{user_id}/roles":{"get":{"tags":["Sol App roles (internal)"],"summary":"List Roles","operationId":"list_roles_api_sol_app_users__user_id__roles_get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Sol App roles (internal)"],"summary":"Create Role","operationId":"create_role_api_sol_app_users__user_id__roles_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/users/{user_id}/roles/prefill":{"get":{"tags":["Sol App roles (internal)"],"summary":"Role Prefill","description":"A draft for a NEW role from the company's memory (buyer-safe facts\nonly; never budget). Empty when memory is off or the domain is not proven.","operationId":"role_prefill_api_sol_app_users__user_id__roles_prefill_get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/users/{user_id}/artifacts":{"get":{"tags":["Sol App roles (internal)"],"summary":"Recent Artifacts","description":"The user's latest documents (id, kind, title) for the attach picker.","operationId":"recent_artifacts_api_sol_app_users__user_id__artifacts_get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":60,"minimum":1,"default":30,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/roles/{role_id}":{"get":{"tags":["Sol App roles (internal)"],"summary":"Get Role","operationId":"get_role_api_sol_app_roles__role_id__get","parameters":[{"name":"role_id","in":"path","required":true,"schema":{"type":"string","title":"Role Id"}},{"name":"user_id","in":"query","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["Sol App roles (internal)"],"summary":"Patch Role","operationId":"patch_role_api_sol_app_roles__role_id__patch","parameters":[{"name":"role_id","in":"path","required":true,"schema":{"type":"string","title":"Role Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RolePatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Sol App roles (internal)"],"summary":"Delete Role","operationId":"delete_role_api_sol_app_roles__role_id__delete","parameters":[{"name":"role_id","in":"path","required":true,"schema":{"type":"string","title":"Role Id"}},{"name":"user_id","in":"query","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/roles/{role_id}/items":{"post":{"tags":["Sol App roles (internal)"],"summary":"Attach Item","operationId":"attach_item_api_sol_app_roles__role_id__items_post","parameters":[{"name":"role_id","in":"path","required":true,"schema":{"type":"string","title":"Role Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/users/{user_id}/roles/attach":{"post":{"tags":["Sol App roles (internal)"],"summary":"Attach By Title","description":"chat-api's ``attach_to_role``: the role by id, else by title (created\nwhen missing). The acting user in the path and the body must match.","operationId":"attach_by_title_api_sol_app_users__user_id__roles_attach_post","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AttachByTitleIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/roles/{role_id}/items/{item_id}":{"delete":{"tags":["Sol App roles (internal)"],"summary":"Detach Item","operationId":"detach_item_api_sol_app_roles__role_id__items__item_id__delete","parameters":[{"name":"role_id","in":"path","required":true,"schema":{"type":"string","title":"Role Id"}},{"name":"item_id","in":"path","required":true,"schema":{"type":"string","title":"Item Id"}},{"name":"user_id","in":"query","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/partners/public/{slug}":{"get":{"tags":["Sol partners (H5)"],"summary":"Public Partner","operationId":"public_partner_api_partners_public__slug__get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/partners/public/{slug}/logo":{"get":{"tags":["Sol partners (H5)"],"summary":"Public Partner Logo","operationId":"public_partner_logo_api_partners_public__slug__logo_get","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string","title":"Slug"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/partners":{"get":{"tags":["Sol partners (H5)"],"summary":"List Partners","operationId":"list_partners_api_partners_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["Sol partners (H5)"],"summary":"Create Partner","operationId":"create_partner_api_partners_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerCreate"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/partners/{partner_id}":{"patch":{"tags":["Sol partners (H5)"],"summary":"Update Partner","operationId":"update_partner_api_partners__partner_id__patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","title":"Partner Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerPatch"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/partners/{partner_id}/logo":{"get":{"tags":["Sol partners (H5)"],"summary":"Partner Logo","operationId":"partner_logo_api_partners__partner_id__logo_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","title":"Partner Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/partners/{partner_id}/report":{"get":{"tags":["Sol partners (H5)"],"summary":"Partner Report","operationId":"partner_report_api_partners__partner_id__report_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"partner_id","in":"path","required":true,"schema":{"type":"string","title":"Partner Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/decision-audit/events":{"get":{"tags":["Decision audit (founder)"],"summary":"List Events","operationId":"list_events_api_decision_audit_events_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"company_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Id"}},{"name":"company_domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":253},{"type":"null"}],"title":"Company Domain"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"To"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Action"}},{"name":"after_id","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","minimum":0},{"type":"null"}],"title":"After Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":200,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/decision-audit/export":{"get":{"tags":["Decision audit (founder)"],"summary":"Export Events","operationId":"export_events_api_decision_audit_export_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"format","in":"query","required":false,"schema":{"enum":["csv","json"],"type":"string","default":"csv","title":"Format"}},{"name":"company_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Id"}},{"name":"company_domain","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":253},{"type":"null"}],"title":"Company Domain"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"To"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Action"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ai-fluency/tasks":{"get":{"tags":["ai-fluency"],"summary":"List Tasks","operationId":"list_tasks_api_ai_fluency_tasks_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/candidates/{candidate_id}/send-ai-fluency":{"post":{"tags":["ai-fluency"],"summary":"Send Ai Fluency","description":"Mint a link and email it. The row is rolled back when the email fails\n(no sent-but-undelivered ghost), same as the coding assessment.","operationId":"send_ai_fluency_api_candidates__candidate_id__send_ai_fluency_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SendIn"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/ai-fluency":{"get":{"tags":["ai-fluency"],"summary":"Candidate Attempts","operationId":"candidate_attempts_api_candidates__candidate_id__ai_fluency_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ai-fluency/{magic_token}":{"get":{"tags":["ai-fluency"],"summary":"Public Get","operationId":"public_get_api_ai_fluency__magic_token__get","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ai-fluency/{magic_token}/start":{"post":{"tags":["ai-fluency"],"summary":"Public Start","operationId":"public_start_api_ai_fluency__magic_token__start_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ai-fluency/{magic_token}/submit":{"post":{"tags":["ai-fluency"],"summary":"Public Submit","operationId":"public_submit_api_ai_fluency__magic_token__submit_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/ai-fluency/{magic_token}/extract":{"post":{"tags":["ai-fluency"],"summary":"Public Extract","description":"An uploaded session export or patch/zip → text for the form.\n\nMultipart form: ``kind`` (diff | agent_log) and ``file``.\n\nOnly for an OPEN task (the token is the credential, as for submit).\nNothing is stored: the page puts the text in the field, the candidate\ncan read and edit it, and submit stores it exactly as a paste.\n\nThe form is parsed BY HAND, after the size and token checks: declaring\n``File(...)`` / ``Form(...)`` params makes FastAPI spool the whole body\n(to disk past 1 MB, with no cap) before this function runs, so the 2 MB\nlimit would only ever be checked after an attacker's gigabyte had been\nwritten. Content-Length is required (every browser FormData upload sends\nit) and the server never reads past it.","operationId":"public_extract_api_ai_fluency__magic_token__extract_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidate/ai-fluency/start":{"post":{"tags":["ai-fluency"],"summary":"Candidate Start","description":"Start (or resume) the optional AI-fluency task for the signed-in\ndeveloper. → {path, expires_at, resumed}. 409 with a reason when it is\npassed, in review or inside the retake cooldown.","operationId":"candidate_start_api_candidate_ai_fluency_start_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/internal/weekly-brief/run":{"post":{"tags":["Weekly hiring brief"],"summary":"Run Brief","operationId":"run_brief_api_internal_weekly_brief_run_post","parameters":[{"name":"x-cron-token","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Cron-Token"}}],"requestBody":{"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/RunIn"},{"type":"null"}],"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/sol-app/users/{user_id}/brief-preference":{"get":{"tags":["Weekly hiring brief"],"summary":"Get Pref","operationId":"get_pref_api_sol_app_users__user_id__brief_preference_get","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"tags":["Weekly hiring brief"],"summary":"Put Pref","operationId":"put_pref_api_sol_app_users__user_id__brief_preference_put","parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PrefIn"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/brief/unsubscribe/{token}":{"get":{"tags":["Weekly hiring brief"],"summary":"Unsubscribe Page","description":"Confirm page. Does NOT apply: corporate link scanners GET every URL\non delivery (same reason as the lead opt-out). Same page for any token.","operationId":"unsubscribe_page_api_brief_unsubscribe__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["Weekly hiring brief"],"summary":"Unsubscribe Apply","description":"Applies. Three callers: the confirm form (→ HTML), Gmail / Yahoo\nRFC 8058 one-click (→ JSON), tools (→ JSON). Never 422; neutral about\nunknown tokens.","operationId":"unsubscribe_apply_api_brief_unsubscribe__token__post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/buyer-verification/request":{"post":{"tags":["Buyer verification (internal)"],"summary":"Request Code","description":"Always ``{sent: true, verification_id, email_masked}`` for a valid work\nemail, whether or not an account exists. A limit only UNKNOWN addresses\nmeet answers the same way, sends nothing and records a withheld row that\nthe 10-minute per-inbox and per-session caps count, so both kinds see\nthe same sequence (#478 M1, follow-up 3). Enumeration is reduced, not\nclosed: a prober can still tell a known address by counting a\nper-source budget with inboxes of its own, at the cost of ONE email to\nit (which the target sees), and the daily cap tells after 10 emails to\nit; see the service module docstring. The email goes out in\nthe background so the answer time does not depend on Resend.","operationId":"request_code_api_buyer_verification_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RequestIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/buyer-verification/confirm":{"post":{"tags":["Buyer verification (internal)"],"summary":"Confirm","operationId":"confirm_api_buyer_verification_confirm_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/buyer-verification/link/consume":{"post":{"tags":["Buyer verification (internal)"],"summary":"Consume","description":"apps/sol only: a single-use emailed link → a Sol App session.","operationId":"consume_api_buyer_verification_link_consume_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumeIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/buyer-verification/link/peek":{"post":{"tags":["Buyer verification (internal)"],"summary":"Peek","description":"apps/sol only, consumes NOTHING: what the confirm page must say before\nthe person presses \"Yes, this is me\" (which AI client asked, for what, for\nwhich masked email). Review A M1 / B5: the button can let an AI client act\nfor this email, so the page names it.","operationId":"peek_api_buyer_verification_link_peek_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConsumeIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/buyer-verification/blocked":{"post":{"tags":["Buyer verification (internal)"],"summary":"Blocked","description":"mcp-server only: PRD §1.8 ``mcp_write_blocked`` for refusals that never\nreached crm-api (missing token, no proxy token; E2E review L3). Closed\nlists: free text from a model never becomes an event property.","operationId":"blocked_api_buyer_verification_blocked_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlockedIn"}}},"required":true},"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/mcp/roles":{"post":{"tags":["MCP (internal)"],"summary":"Save Role","operationId":"save_role_api_mcp_roles_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/McpRoleIn"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/integrity":{"get":{"tags":["Integrity"],"summary":"Get Candidate Integrity","operationId":"get_candidate_integrity_api_candidates__candidate_id__integrity_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/integrity/signals/{signal_id}/resolve":{"post":{"tags":["Integrity"],"summary":"Resolve Signal","operationId":"resolve_signal_api_candidates__candidate_id__integrity_signals__signal_id__resolve_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}},{"name":"signal_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Signal Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResolveBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/integrity/review":{"post":{"tags":["Integrity"],"summary":"Mark Candidate Reviewed","operationId":"mark_candidate_reviewed_api_candidates__candidate_id__integrity_review_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/integrity/restore":{"post":{"tags":["Integrity"],"summary":"Restore Candidate To Bench","description":"The only exit from ``fraud_confirmed``. Who + when + the written\nreason land on the candidate row and in integrity_status_events.","operationId":"restore_candidate_to_bench_api_candidates__candidate_id__integrity_restore_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RestoreBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/integrity/live-call":{"post":{"tags":["Integrity"],"summary":"Record Live Call","operationId":"record_live_call_api_candidates__candidate_id__integrity_live_call_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LiveCallBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/integrity/test-marker/preview":{"get":{"tags":["Integrity"],"summary":"Preview Test Marker","description":"Read only, for the toggle's confirm dialog (founder only): the\ncandidate's CURRENT integrity status (so the dialog knows whether a\nreason is required), and the real candidates the change would release\n(mark; never in production) or re-hold (unmark), with names.","operationId":"preview_test_marker_api_candidates__candidate_id__integrity_test_marker_preview_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}},{"name":"is_test","in":"query","required":true,"schema":{"type":"boolean","title":"Is Test"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/integrity/test-marker":{"post":{"tags":["Integrity"],"summary":"Set Test Marker","description":"Mark / unmark a test candidate. Founder only (the same as the UI;\ninternal_admin cannot Review / Restore either, so it must not get an\nindirect release power here). A held candidate needs a reason of at\nleast 10 characters (422 otherwise); every call is logged in\nintegrity_status_events. Outside production marking also releases real\ncandidates whose E flag named only test accounts; unmarking re-holds\nthem (every environment).","operationId":"set_test_marker_api_candidates__candidate_id__integrity_test_marker_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestMarkerBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-assessment/{magic_token}/followup":{"get":{"tags":["code-followup"],"summary":"Open Followup","operationId":"open_followup_api_coding_assessment__magic_token__followup_get","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-assessment/{magic_token}/followup/consent":{"post":{"tags":["code-followup"],"summary":"Consent Followup","operationId":"consent_followup_api_coding_assessment__magic_token__followup_consent_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-assessment/{magic_token}/followup/reveal":{"post":{"tags":["code-followup"],"summary":"Reveal Followup","operationId":"reveal_followup_api_coding_assessment__magic_token__followup_reveal_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-assessment/{magic_token}/followup/start":{"post":{"tags":["code-followup"],"summary":"Start Followup Take","operationId":"start_followup_take_api_coding_assessment__magic_token__followup_start_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-assessment/{magic_token}/followup/skip":{"post":{"tags":["code-followup"],"summary":"Skip Followup","operationId":"skip_followup_api_coding_assessment__magic_token__followup_skip_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/coding-assessment/{magic_token}/followup/video":{"post":{"tags":["code-followup"],"summary":"Upload Followup Video","operationId":"upload_followup_video_api_coding_assessment__magic_token__followup_video_post","parameters":[{"name":"magic_token","in":"path","required":true,"schema":{"type":"string","title":"Magic Token"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_followup_video_api_coding_assessment__magic_token__followup_video_post"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/candidates/{candidate_id}/code-followup":{"get":{"tags":["code-followup"],"summary":"Get Candidate Code Followup","operationId":"get_candidate_code_followup_api_candidates__candidate_id__code_followup_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"candidate_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Candidate Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/public/placement-check/{token}":{"get":{"tags":["Integrity"],"summary":"Placement Check View","operationId":"placement_check_view_api_public_placement_check__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/public/placement-check/{token}/still":{"get":{"tags":["Integrity"],"summary":"Placement Check Still","operationId":"placement_check_still_api_public_placement_check__token__still_get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/public/placement-check/{token}/answer":{"post":{"tags":["Integrity"],"summary":"Placement Check Answer","operationId":"placement_check_answer_api_public_placement_check__token__answer_post","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnswerBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AccessLogEntry":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"document_id":{"type":"string","format":"uuid","title":"Document Id"},"accessed_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Accessed By"},"accessed_by_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Accessed By Email"},"accessed_for_client_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Accessed For Client Id"},"project_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Project Id"},"action":{"type":"string","enum":["download","view","email_send","email_open"],"title":"Action"},"track_id":{"type":"string","title":"Track Id"},"ip_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ip Address"},"user_agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Agent"},"accessed_at":{"type":"string","format":"date-time","title":"Accessed At"}},"type":"object","required":["id","document_id","accessed_by","accessed_for_client_id","project_id","action","track_id","ip_address","user_agent","accessed_at"],"title":"AccessLogEntry","description":"Row in GET /api/projects/{id}/access-log or\nGET /api/candidates/{id}/document-access-log."},"Account":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"status":{"type":"string","title":"Status","default":"Healthy"},"session_path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Path"},"daily_connections":{"type":"integer","title":"Daily Connections","default":0},"daily_messages":{"type":"integer","title":"Daily Messages","default":0}},"type":"object","required":["name","email"],"title":"Account"},"AccountHealth":{"properties":{"status":{"type":"string","title":"Status"},"connections_used":{"type":"integer","title":"Connections Used"},"connections_limit":{"type":"integer","title":"Connections Limit"},"messages_used":{"type":"integer","title":"Messages Used"},"messages_limit":{"type":"integer","title":"Messages Limit"},"warning":{"type":"boolean","title":"Warning","default":false}},"type":"object","required":["status","connections_used","connections_limit","messages_used","messages_limit"],"title":"AccountHealth"},"ActivateLeadsRequest":{"properties":{"lead_ids":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":500,"minItems":1,"title":"Lead Ids"}},"type":"object","required":["lead_ids"],"title":"ActivateLeadsRequest","description":"Move selected leads from auto_send_status='pending_activation' to\n'ready_to_send'. Used by the dashboard \"Activate selected\" button.\n\nFounder + internal_admin only because this opens the gate to real\noutbound sends — same blast-radius class as flipping the global flag,\njust per-lead. UUID4 validation rejects malformed IDs at the API edge\nso we return a clean 422 instead of asyncpg's 500 on a bad CAST."},"ActivityLog":{"properties":{"id":{"type":"string","title":"Id"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"action":{"type":"string","title":"Action"},"details":{"type":"string","title":"Details"},"user":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User"}},"type":"object","required":["id","timestamp","action","details"],"title":"ActivityLog"},"AddNoteRequest":{"properties":{"content":{"type":"string","title":"Content"},"note_type":{"type":"string","title":"Note Type","default":"note"}},"type":"object","required":["content"],"title":"AddNoteRequest"},"AddRoleBody":{"properties":{"role_slug":{"type":"string","maxLength":80,"minLength":1,"title":"Role Slug"}},"type":"object","required":["role_slug"],"title":"AddRoleBody"},"AnswerBody":{"properties":{"answer":{"type":"string","enum":["yes","no","not_sure"],"title":"Answer"},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note"}},"type":"object","required":["answer"],"title":"AnswerBody"},"ApproveRequest":{"properties":{"item_ids":{"items":{"type":"string"},"type":"array","title":"Item Ids"}},"type":"object","required":["item_ids"],"title":"ApproveRequest"},"AssessmentEventRequest":{"properties":{"event":{"type":"string","title":"Event"},"viewport_w":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Viewport W"},"viewport_h":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Viewport H"},"ua_family":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ua Family"}},"type":"object","required":["event"],"title":"AssessmentEventRequest","description":"One funnel event. Sent by beacon, so it must never need a reply.\n\nEVERY FIELD COERCES; NOTHING REJECTS. The handler answers 202 on every\npath precisely because `sendBeacon` cannot read a response or retry —\nbut Pydantic runs BEFORE the handler, so a bound expressed as `le=` or\n`max_length=` turns into a 422 the beacon never sees and an event that\nis simply gone.\n\nThat was not theoretical. A plain macOS Chrome user-agent is 47\ncharacters against the old `max_length=40`, so a client passing\n`navigator.userAgent` would have lost 100% of its events, silently, and\nthe funnel this instrumentation exists to measure would have read as\nempty rather than as broken.\n\nTruncating a 47-character UA to 40 costs a suffix nobody groups by.\nRejecting it costs the whole row. The bounds are still enforced — they\nare just enforced by clamping, which is what a telemetry sink should do\nwith a value it does not like."},"AssessmentResponse":{"properties":{"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"status":{"type":"string","enum":["not_sent","sent","passed","failed","expired"],"title":"Status"},"code_challenge_link":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code Challenge Link"},"code_challenge_assessment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Code Challenge Assessment Id"},"score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Score"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"sent_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Sent At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"candidate_status":{"type":"string","title":"Candidate Status"}},"type":"object","required":["candidate_id","status","code_challenge_link","code_challenge_assessment_id","score","notes","sent_at","completed_at","candidate_status"],"title":"AssessmentResponse","description":"Returned by all L2 endpoints. Shape mirrors the candidate columns."},"AttachByTitleIn":{"properties":{"user_id":{"type":"string","title":"User Id"},"kind":{"type":"string","enum":["artifact","engineer"],"title":"Kind"},"ref":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Ref"},"artifact":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Artifact"},"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id"},"artifact_kind":{"anyOf":[{"type":"string","enum":["interview_kit","scorecard","job_post"]},{"type":"null"}],"title":"Artifact Kind"},"via":{"type":"string","enum":["app","chat"],"title":"Via","default":"app"},"role_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Id"},"role_title":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Role Title"},"create_if_missing":{"type":"boolean","title":"Create If Missing","default":true}},"type":"object","required":["user_id","kind"],"title":"AttachByTitleIn"},"AttachIn":{"properties":{"user_id":{"type":"string","title":"User Id"},"kind":{"type":"string","enum":["artifact","engineer"],"title":"Kind"},"ref":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Ref"},"artifact":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Artifact"},"conversation_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Conversation Id"},"artifact_kind":{"anyOf":[{"type":"string","enum":["interview_kit","scorecard","job_post"]},{"type":"null"}],"title":"Artifact Kind"},"via":{"type":"string","enum":["app","chat"],"title":"Via","default":"app"}},"type":"object","required":["user_id","kind"],"title":"AttachIn"},"BackfillRequest":{"properties":{"limit_interviews":{"type":"integer","maximum":200.0,"minimum":1.0,"title":"Limit Interviews","default":10},"dry_run":{"type":"boolean","title":"Dry Run","default":true},"retry_failed":{"type":"boolean","title":"Retry Failed","default":false},"interview_ids":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":200},{"type":"null"}],"title":"Interview Ids"}},"type":"object","title":"BackfillRequest"},"BatchTransferRequest":{"properties":{"transfers":{"items":{"$ref":"#/components/schemas/TransferRequest"},"type":"array","title":"Transfers"}},"type":"object","required":["transfers"],"title":"BatchTransferRequest","description":"Batch transfer request"},"BatchTransferResponse":{"properties":{"total_transfers":{"type":"integer","title":"Total Transfers"},"successful":{"type":"integer","title":"Successful"},"failed":{"type":"integer","title":"Failed"},"total_amount_usd":{"type":"number","title":"Total Amount Usd"},"total_fees_usd":{"type":"number","title":"Total Fees Usd"},"results":{"items":{"$ref":"#/components/schemas/TransferResponse"},"type":"array","title":"Results"}},"type":"object","required":["total_transfers","successful","failed","total_amount_usd","total_fees_usd","results"],"title":"BatchTransferResponse","description":"Batch transfer response"},"BenchBarStatOut":{"properties":{"eligible":{"type":"boolean","title":"Eligible"},"one_in_n":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"One In N"}},"type":"object","required":["eligible"],"title":"BenchBarStatOut","description":"G1 addendum §4: \"Only about 1 in N applicants\" pass both bars.\n\nOne number for the whole bench, never per engineer. ``one_in_n`` is\n``None`` (and ``eligible`` false) whenever BENCH_BAR_STAT_ENABLED is off,\nfewer than 100 of our people have been assessed, or the computation\nfailed. The consumer hides the line in every one of those cases."},"BenchCardOut":{"properties":{"display_name":{"type":"string","title":"Display Name"},"seniority_label":{"type":"string","title":"Seniority Label"},"years_experience_range":{"type":"string","title":"Years Experience Range"},"availability_window":{"type":"string","title":"Availability Window"},"bio":{"type":"string","title":"Bio"},"skills_display":{"items":{"type":"string"},"type":"array","title":"Skills Display"},"timezone_overlap_hours":{"type":"integer","title":"Timezone Overlap Hours"},"stacks_verified":{"items":{"type":"string"},"type":"array","title":"Stacks Verified"},"stack_slugs":{"items":{"type":"string"},"type":"array","title":"Stack Slugs"},"ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ref"},"intent":{"anyOf":[{"$ref":"#/components/schemas/BenchIntentOut"},{"type":"null"}]}},"type":"object","required":["display_name","seniority_label","years_experience_range","availability_window","bio","skills_display","timezone_overlap_hours"],"title":"BenchCardOut","description":"One blind card. Field names match the pSEO ``ProfileCard`` shape so the\nsame React component renders a baked pSEO page and this live page.\n\n``skills_display`` is résumé-CLAIMED. ``stacks_verified`` is the display\nname of every assessment package the engineer has PASSED. They come from\ndifferent tables through different code paths and a renderer may use the\nword \"verified\" for the second list only (Wave 3 D6)."},"BenchIntentOut":{"properties":{"work_types":{"items":{"type":"string","enum":["greenfield","ai_ml","product","backend_heavy","frontend_heavy","data","platform_infra","mobile","modernization"]},"type":"array","maxItems":3,"title":"Work Types"},"team_size":{"anyOf":[{"type":"string","enum":["solo","small","mid","large","any"]},{"type":"null"}],"title":"Team Size"},"engagement":{"anyOf":[{"type":"string","enum":["short","medium","long","any"]},{"type":"null"}],"title":"Engagement"}},"type":"object","title":"BenchIntentOut","description":"Sol feature #7: what the engineer wants. Closed-vocabulary codes only\n(``ruzora_db.engineer_intent``); the Literal types make this response model\na third gate after the DB CHECK and ``blind_intent``."},"BenchPreviewRequest":{"properties":{"role":{"type":"string","maxLength":200,"minLength":1,"title":"Role"},"role_slug":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Role Slug"},"seniority":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Seniority"},"skills":{"items":{"type":"string"},"type":"array","maxItems":20,"minItems":1,"title":"Skills"},"engineers":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Engineers"},"timezone_overlap":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Timezone Overlap"}},"type":"object","required":["role","skills"],"title":"BenchPreviewRequest","description":"Body of ``POST /api/forms/bench-preview`` (Sol hero, PRD §5.1b FR-4b).\n\nThe pre-gate slice of ``ShortlistRequestCreate``: role + stack, nothing\nidentity-bearing. ``skills`` is a list because that is what the tool\nschema sends; the matching path accepts either form. ``engineers`` and\n``timezone_overlap`` are accepted so the tool and intake schemas stay one\nshape; neither drives matching today (nor does it in the intake).\n\nBounds are tight on purpose — this is anonymous and rate-limited, and\nevery field reaches a SQL bind or a log line."},"BenchStackOut":{"properties":{"slug":{"type":"string","title":"Slug"},"label":{"type":"string","title":"Label"}},"type":"object","required":["slug","label"],"title":"BenchStackOut","description":"A filter chip: label only. No engineer count (see PublicBenchOut)."},"BlockedIn":{"properties":{"tool":{"type":"string","maxLength":60,"title":"Tool"},"reason":{"type":"string","maxLength":40,"title":"Reason"}},"type":"object","required":["tool","reason"],"title":"BlockedIn"},"Body_import_candidates_csv_api_sourcing_import_csv_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_import_candidates_csv_api_sourcing_import_csv_post"},"Body_import_leads_csv_api_sales_import_csv_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_import_leads_csv_api_sales_import_csv_post"},"Body_import_vibe_prospecting_csv_api_sales_import_vibe_prospecting_csv_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_import_vibe_prospecting_csv_api_sales_import_vibe_prospecting_csv_post"},"Body_mpc_tick_api_outbound_mpc_tick_post":{"properties":{"dry_run":{"type":"boolean","title":"Dry Run","default":false},"limit":{"anyOf":[{"type":"integer","maximum":200.0,"minimum":1.0},{"type":"null"}],"title":"Limit"},"max_postings":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":1.0},{"type":"null"}],"title":"Max Postings"},"cursor":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Cursor"}},"type":"object","title":"Body_mpc_tick_api_outbound_mpc_tick_post"},"Body_outbound_heartbeat_api_outbound_heartbeat_post":{"properties":{"dry_run":{"type":"boolean","title":"Dry Run","default":false},"once_per_day":{"type":"boolean","title":"Once Per Day","default":false}},"type":"object","title":"Body_outbound_heartbeat_api_outbound_heartbeat_post"},"Body_upload_and_parse_resume_api_candidates__candidate_id__resume_post":{"properties":{"file":{"anyOf":[{"type":"string","format":"binary"},{"type":"null"}],"title":"File"},"resume_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resume Text"}},"type":"object","title":"Body_upload_and_parse_resume_api_candidates__candidate_id__resume_post"},"Body_upload_followup_video_api_coding_assessment__magic_token__followup_video_post":{"properties":{"video":{"type":"string","format":"binary","title":"Video"},"camera_label":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Camera Label"},"take":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Take"}},"type":"object","required":["video"],"title":"Body_upload_followup_video_api_coding_assessment__magic_token__followup_video_post"},"Body_upload_response_interview__magic_token__responses__question_id__post":{"properties":{"video":{"type":"string","format":"binary","title":"Video"},"camera_label":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Camera Label"},"reveal_to_record_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Reveal To Record Ms"},"take":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Take"}},"type":"object","required":["video"],"title":"Body_upload_response_interview__magic_token__responses__question_id__post"},"Body_upload_resume_api_bench_profile__token__resume_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_resume_api_bench_profile__token__resume_post"},"Body_upload_resume_api_forms_upload_resume_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"},"candidate_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Candidate Id"}},"type":"object","required":["file"],"title":"Body_upload_resume_api_forms_upload_resume_post"},"BulkAddRequest":{"properties":{"campaign_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign Id"},"entity_type":{"type":"string","title":"Entity Type"},"entities":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Entities"},"connect_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connect Note"},"message_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Body"},"followup_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Followup Body"},"sourcing_job_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sourcing Job Id"}},"type":"object","required":["entity_type","entities"],"title":"BulkAddRequest"},"BulkSendLiveScreenInviteRequest":{"properties":{"candidate_ids":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":50,"minItems":1,"title":"Candidate Ids"}},"type":"object","required":["candidate_ids"],"title":"BulkSendLiveScreenInviteRequest","description":"POST /api/candidates/bulk/send-live-screen-invite payload.\n\nCapped at 50 ids per call. Per-candidate failures are isolated — one\nbad id does not abort the batch (each is reported under `skipped`)."},"BulkSendLiveScreenInviteResponse":{"properties":{"sent":{"type":"integer","title":"Sent"},"skipped_count":{"type":"integer","title":"Skipped Count"},"skipped":{"items":{"$ref":"#/components/schemas/BulkSkippedItem"},"type":"array","title":"Skipped"},"results":{"items":{"$ref":"#/components/schemas/BulkSentItem"},"type":"array","title":"Results"}},"type":"object","required":["sent","skipped_count","skipped","results"],"title":"BulkSendLiveScreenInviteResponse"},"BulkSentItem":{"properties":{"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"meeting_id":{"type":"string","format":"uuid","title":"Meeting Id"}},"type":"object","required":["candidate_id","meeting_id"],"title":"BulkSentItem"},"BulkSkippedItem":{"properties":{"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"reason":{"type":"string","enum":["not_found","no_email","already_invited","interview_not_passed","send_failed"],"title":"Reason"},"detail":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Detail"}},"type":"object","required":["candidate_id","reason"],"title":"BulkSkippedItem"},"Candidate":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name"},"github_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Github Url"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"location":{"type":"string","title":"Location"},"skills":{"items":{"type":"string"},"type":"array","title":"Skills","default":[]},"score":{"type":"integer","title":"Score","default":0},"score_analysis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Score Analysis"},"status":{"type":"string","title":"Status","default":"New"},"source":{"type":"string","title":"Source","default":"GitHub"},"bio_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio Summary"},"current_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Role"},"skill_ratings":{"anyOf":[{"additionalProperties":{"type":"integer"},"type":"object"},{"type":"null"}],"title":"Skill Ratings"},"experience_entries":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Experience Entries"},"education":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Education"},"certifications":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Certifications"},"overall_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Overall Score"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"},"availability_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Availability Status"},"technical_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Technical Score"},"communication_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Communication Score"},"ai_readiness_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ai Readiness Score"}},"additionalProperties":true,"type":"object","required":["name","location"],"title":"Candidate","description":"Write shape — the ``POST /api/candidates`` request body.\n\nSame fields as :class:`CandidateRead` plus the availability vocabulary\nguard. Never use this as a ``response_model``: it rejects ``'stale'``,\nwhich is a legitimate stored value."},"CandidateAssessmentView":{"properties":{"title":{"type":"string","title":"Title"},"kind":{"type":"string","enum":["coding","questions"],"title":"Kind","default":"coding"},"language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Language"},"difficulty":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Difficulty"},"problem_md":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Problem Md"},"starter_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Starter Code"},"visible_tests":{"items":{"$ref":"#/components/schemas/TestCase"},"type":"array","title":"Visible Tests","default":[]},"time_limit_s":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Time Limit S"},"status":{"type":"string","enum":["sent","in_progress","submitted","graded","expired","errored"],"title":"Status"},"submitted_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submitted Code"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"submitted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Submitted At"},"candidate_first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Candidate First Name"},"draft_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Draft Code"},"draft_answers":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Draft Answers"},"draft_saved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Draft Saved At"},"elapsed_seconds":{"type":"integer","title":"Elapsed Seconds","default":0},"budget_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Budget Seconds"},"remaining_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Remaining Seconds"},"package_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Package Name"},"estimated_minutes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Estimated Minutes"},"package_questions":{"items":{"$ref":"#/components/schemas/PackageQuestionView"},"type":"array","title":"Package Questions","default":[]},"question_count":{"type":"integer","title":"Question Count","default":0},"page_options":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Page Options"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context"},"integrity":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Integrity"}},"type":"object","required":["title","status","expires_at"],"title":"CandidateAssessmentView","description":"Public payload candidates see at /assessment/{token}.\n\nCritically excludes:\n  - hidden_tests (inputs never leave the server)\n  - score / ai_reasoning (recruiter-only signal — see ADR on\n    recruiter-controlled feedback)\n  - question expected_signal_md (rubric — recruiter-only)"},"CandidateInterviewResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"template_id":{"type":"string","format":"uuid","title":"Template Id"},"template_name":{"type":"string","title":"Template Name"},"status":{"type":"string","enum":["sent","in_progress","completed","expired","reviewed"],"title":"Status"},"sent_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Sent At"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"reviewed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reviewed At"},"overall_ai_score":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Overall Ai Score"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"responses":{"items":{"$ref":"#/components/schemas/InterviewResponseRow"},"type":"array","title":"Responses","default":[]}},"type":"object","required":["id","candidate_id","template_id","template_name","status","sent_at","expires_at","started_at","completed_at","reviewed_at","overall_ai_score","created_at"],"title":"CandidateInterviewResponse","description":"Recruiter-facing detail view: interview + all responses + question text."},"CandidateRead":{"properties":{"id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Id"},"name":{"type":"string","title":"Name"},"github_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Github Url"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"location":{"type":"string","title":"Location"},"skills":{"items":{"type":"string"},"type":"array","title":"Skills","default":[]},"score":{"type":"integer","title":"Score","default":0},"score_analysis":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Score Analysis"},"status":{"type":"string","title":"Status","default":"New"},"source":{"type":"string","title":"Source","default":"GitHub"},"bio_summary":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio Summary"},"current_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Role"},"skill_ratings":{"anyOf":[{"additionalProperties":{"type":"integer"},"type":"object"},{"type":"null"}],"title":"Skill Ratings"},"experience_entries":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Experience Entries"},"education":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Education"},"certifications":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Certifications"},"overall_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Overall Score"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"},"availability_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Availability Status"},"technical_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Technical Score"},"communication_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Communication Score"},"ai_readiness_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ai Readiness Score"}},"additionalProperties":true,"type":"object","required":["name","location"],"title":"CandidateRead","description":"Read shape for candidate rows.\n\nDeliberately carries NO availability vocabulary validator. This is the\n``response_model`` for the recruiter list/detail endpoints, so it must\naccept **every value the database can legally hold** — including the\nsystem-only ``'stale'`` marker written by the bench staleness tick\n(``bench_staleness_service``, migration ``w2a4stale``) and legacy\nNULLs. A response_model rejects the whole response when one row fails,\nso a read-side validator here turns a single stale candidate into a\n500 for the entire list. Write-side vocabulary enforcement lives on\nthe ``Candidate`` subclass below."},"CandidateReferralCreate":{"properties":{"referred_name":{"type":"string","maxLength":255,"minLength":2,"title":"Referred Name","description":"Full name of referred person"},"referred_email":{"type":"string","format":"email","title":"Referred Email","description":"Email of referred person"},"referred_linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referred Linkedin Url","description":"LinkedIn profile URL"},"referred_github_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referred Github Url","description":"GitHub profile URL"},"referred_skills":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Referred Skills","description":"Comma-separated skills"},"referred_location":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Referred Location","description":"Country/city location"},"referral_reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Referral Reason","description":"Why they're a good fit"},"relationship":{"type":"string","enum":["Former Colleague","Friend","Mentor/Mentee","Other"],"title":"Relationship","description":"Relationship with referred person"},"current_role":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Current Role","description":"Current job title"},"current_company":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Current Company","description":"Current employer"}},"type":"object","required":["referred_name","referred_email","relationship"],"title":"CandidateReferralCreate","description":"Submit a new candidate referral"},"CandidateReferralListItem":{"properties":{"id":{"type":"string","title":"Id"},"referred_name":{"type":"string","title":"Referred Name"},"referred_email":{"type":"string","title":"Referred Email"},"status":{"type":"string","title":"Status"},"quality_score":{"type":"integer","title":"Quality Score"},"reward_status":{"type":"string","title":"Reward Status"},"estimated_reward":{"type":"string","title":"Estimated Reward"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","referred_name","referred_email","status","quality_score","reward_status","estimated_reward","created_at"],"title":"CandidateReferralListItem","description":"Simplified referral for list view"},"CandidateReferralListResponse":{"properties":{"referrals":{"items":{"$ref":"#/components/schemas/CandidateReferralListItem"},"type":"array","title":"Referrals"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"}},"type":"object","required":["referrals","total","page","per_page"],"title":"CandidateReferralListResponse","description":"Paginated list of candidate referrals"},"CandidateReferralResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Record ID"},"referrer_type":{"type":"string","title":"Referrer Type"},"referrer_email":{"type":"string","title":"Referrer Email"},"referred_name":{"type":"string","title":"Referred Name"},"referred_email":{"type":"string","title":"Referred Email"},"referred_linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referred Linkedin Url"},"referred_github_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referred Github Url"},"referred_skills":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referred Skills"},"referred_location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referred Location"},"referral_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referral Reason"},"relationship":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Relationship"},"current_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Role"},"current_company":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Company"},"status":{"type":"string","title":"Status"},"quality_score":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Quality Score","description":"Quality score 0-100"},"duplicate_of_candidate_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Duplicate Of Candidate Id"},"created_candidate_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created Candidate Id"},"matched_placement_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Matched Placement Id"},"reward_status":{"type":"string","title":"Reward Status"},"reward_amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Reward Amount"},"reward_paid_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reward Paid Date"},"conversion_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Conversion Date"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"estimated_reward":{"type":"string","title":"Estimated Reward","description":"Display text like '$500' or '10% off invoice'"},"status_history":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Status History","description":"Status change audit trail"},"auto_reward":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Auto Reward","description":"Auto-reward result if triggered"}},"type":"object","required":["id","referrer_type","referrer_email","referred_name","referred_email","status","quality_score","reward_status","created_at","estimated_reward"],"title":"CandidateReferralResponse","description":"Candidate referral details"},"CandidateReferralUpdate":{"properties":{"status":{"anyOf":[{"type":"string","enum":["Submitted","Under Review","Qualified","Contacted","Screening","Placed","Rejected","Lost","Duplicate"]},{"type":"null"}],"title":"Status"},"qualification_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Qualification Notes","description":"Founder notes on qualification"},"created_candidate_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created Candidate Id","description":"Candidate ID if converted"},"matched_placement_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Matched Placement Id","description":"Placement ID if placed"},"reward_status":{"anyOf":[{"type":"string","enum":["Pending","Qualified","Approved","Paid","Ineligible"]},{"type":"null"}],"title":"Reward Status"},"reward_amount":{"anyOf":[{"type":"number","minimum":0.0},{"type":"null"}],"title":"Reward Amount","description":"Reward amount in USD"}},"type":"object","title":"CandidateReferralUpdate","description":"Update candidate referral (founder only)"},"ChallengeSummary":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"title":{"type":"string","title":"Title"},"language":{"type":"string","title":"Language"},"difficulty":{"type":"string","title":"Difficulty"},"is_seed":{"type":"boolean","title":"Is Seed"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","slug","title","language","difficulty","is_seed","created_at"],"title":"ChallengeSummary","description":"Lightweight row for list endpoints + recruiter dropdown."},"ChatLogRequest":{"properties":{"session_id":{"type":"string","format":"uuid","title":"Session Id"},"surface":{"type":"string","pattern":"^(intake|shortlist|lp|home)$","title":"Surface"},"visitor_email":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Visitor Email"},"lead_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Lead Id"},"shortlist_token":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Shortlist Token"},"turns":{"items":{"$ref":"#/components/schemas/ChatTurnIn"},"type":"array","maxItems":10,"minItems":1,"title":"Turns"}},"type":"object","required":["session_id","surface","turns"],"title":"ChatLogRequest","description":"One completed conversation turn (user message + assistant reply)."},"ChatTurnIn":{"properties":{"role":{"type":"string","pattern":"^(user|assistant)$","title":"Role"},"content":{"type":"string","maxLength":20000,"minLength":1,"title":"Content"},"tools_used":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tools Used"}},"type":"object","required":["role","content"],"title":"ChatTurnIn"},"CheckinCreate":{"properties":{"checkin_type":{"type":"string","pattern":"^(weekly|monthly|ad_hoc)$","title":"Checkin Type"},"responder_type":{"type":"string","pattern":"^(client|candidate)$","title":"Responder Type"},"client_satisfaction":{"anyOf":[{"type":"integer","maximum":5.0,"minimum":1.0},{"type":"null"}],"title":"Client Satisfaction"},"candidate_satisfaction":{"anyOf":[{"type":"integer","maximum":5.0,"minimum":1.0},{"type":"null"}],"title":"Candidate Satisfaction"},"would_hire_again":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Would Hire Again"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"issues_flagged":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Issues Flagged"},"action_items":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Action Items"}},"type":"object","required":["checkin_type","responder_type"],"title":"CheckinCreate"},"ClaimAnonIn":{"properties":{"user_id":{"type":"string","title":"User Id"},"anon_id":{"type":"string","maxLength":64,"title":"Anon Id"}},"type":"object","required":["user_id","anon_id"],"title":"ClaimAnonIn"},"ClientReferralCreate":{"properties":{"referred_company_name":{"type":"string","maxLength":255,"minLength":2,"title":"Referred Company Name","description":"Company name"},"referred_contact_name":{"type":"string","maxLength":255,"minLength":2,"title":"Referred Contact Name","description":"Decision maker name"},"referred_contact_email":{"type":"string","format":"email","title":"Referred Contact Email","description":"Contact email"},"referred_contact_title":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Referred Contact Title","description":"Job title"},"referred_company_domain":{"type":"string","maxLength":255,"minLength":2,"title":"Referred Company Domain","description":"Company domain (e.g., acme.com)"},"referred_company_size":{"type":"string","enum":["1-50","51-200","201-500","500+"],"title":"Referred Company Size","description":"Estimated company size"},"referred_industry":{"type":"string","enum":["SaaS","FinTech","AI/ML","E-commerce","Other"],"title":"Referred Industry","description":"Industry"},"estimated_pricing_tier":{"type":"string","enum":["Pilot","Growth","Squad"],"title":"Estimated Pricing Tier","description":"Projected pricing tier"},"referral_reason":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Referral Reason","description":"Why they're a good fit"},"specific_need":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Specific Need","description":"Current hiring pain/need"}},"type":"object","required":["referred_company_name","referred_contact_name","referred_contact_email","referred_company_domain","referred_company_size","referred_industry","estimated_pricing_tier"],"title":"ClientReferralCreate","description":"Submit a new client/company referral"},"ClientReferralLeaderboard":{"properties":{"leaderboard":{"items":{"$ref":"#/components/schemas/LeaderboardEntry"},"type":"array","title":"Leaderboard"},"period":{"type":"string","title":"Period","description":"e.g., 'all_time', 'this_quarter'"}},"type":"object","required":["leaderboard","period"],"title":"ClientReferralLeaderboard","description":"Referral leaderboard"},"ClientReferralListItem":{"properties":{"id":{"type":"string","title":"Id"},"referred_company_name":{"type":"string","title":"Referred Company Name"},"status":{"type":"string","title":"Status"},"qualification_score":{"type":"integer","title":"Qualification Score"},"estimated_reward":{"type":"string","title":"Estimated Reward"},"reward_status":{"type":"string","title":"Reward Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"assigned_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned To"}},"type":"object","required":["id","referred_company_name","status","qualification_score","estimated_reward","reward_status","created_at"],"title":"ClientReferralListItem","description":"Simplified referral for list view"},"ClientReferralListResponse":{"properties":{"referrals":{"items":{"$ref":"#/components/schemas/ClientReferralListItem"},"type":"array","title":"Referrals"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"}},"type":"object","required":["referrals","total","page","per_page"],"title":"ClientReferralListResponse","description":"Paginated list of client referrals"},"ClientReferralResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Record ID"},"referral_type":{"type":"string","enum":["Client","Candidate"],"title":"Referral Type"},"referrer_name":{"type":"string","title":"Referrer Name","description":"Name of person who referred"},"referrer_company":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Company","description":"Referrer's company (if client)"},"referred_company_name":{"type":"string","title":"Referred Company Name"},"referred_contact_name":{"type":"string","title":"Referred Contact Name"},"referred_contact_email":{"type":"string","title":"Referred Contact Email"},"referred_contact_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referred Contact Title"},"referred_company_domain":{"type":"string","title":"Referred Company Domain"},"referred_company_size":{"type":"string","title":"Referred Company Size"},"referred_industry":{"type":"string","title":"Referred Industry"},"estimated_pricing_tier":{"type":"string","title":"Estimated Pricing Tier"},"referral_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referral Reason"},"specific_need":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Specific Need"},"status":{"type":"string","title":"Status"},"qualification_score":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Qualification Score","description":"Qualification score 0-100"},"qualification_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Qualification Notes"},"assigned_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned To"},"demo_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Demo Date"},"signed_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signed Date"},"lost_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lost Reason"},"converted_company_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Converted Company Id"},"reward_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reward Tier"},"reward_amount":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Reward Amount"},"reward_status":{"type":"string","title":"Reward Status"},"reward_paid_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Reward Paid Date"},"reward_payment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reward Payment Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"estimated_reward":{"type":"string","title":"Estimated Reward","description":"Display text like '$2,000'"},"status_history":{"items":{"additionalProperties":{"type":"string"},"type":"object"},"type":"array","title":"Status History","description":"Status change history"},"auto_reward":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Auto Reward","description":"Auto-reward result when status changed to Signed"}},"type":"object","required":["id","referral_type","referrer_name","referred_company_name","referred_contact_name","referred_contact_email","referred_company_domain","referred_company_size","referred_industry","estimated_pricing_tier","status","qualification_score","reward_status","created_at","estimated_reward"],"title":"ClientReferralResponse","description":"Client referral details"},"ClientReferralStats":{"properties":{"total_referrals":{"type":"integer","title":"Total Referrals"},"by_status":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Status","description":"Count by status"},"by_referrer_type":{"additionalProperties":{"type":"integer"},"type":"object","title":"By Referrer Type","description":"Client vs Candidate"},"conversion_rate":{"type":"number","title":"Conversion Rate","description":"Percentage that signed"},"avg_time_to_close_days":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Time To Close Days"},"total_rewards_paid":{"type":"number","title":"Total Rewards Paid"},"avg_reward":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Reward"},"top_tier":{"type":"string","title":"Top Tier","description":"Most common tier (Pilot, Growth, Squad)"},"roi":{"additionalProperties":{"type":"number"},"type":"object","title":"Roi","description":"ROI metrics: total_contract_value, total_rewards_paid, roi_multiple"}},"type":"object","required":["total_referrals","by_status","by_referrer_type","conversion_rate","total_rewards_paid","top_tier","roi"],"title":"ClientReferralStats","description":"Overall client referral program stats (founder only)"},"ClientReferralUpdate":{"properties":{"status":{"anyOf":[{"type":"string","enum":["Submitted","Qualified","Contacted","Demo_Scheduled","Proposal_Sent","Signed","Lost","Rejected"]},{"type":"null"}],"title":"Status"},"qualification_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Qualification Notes","description":"Founder notes"},"assigned_to":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned To","description":"User ID of founder handling this"},"demo_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Demo Date","description":"Scheduled demo date (ISO format)"},"signed_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signed Date","description":"When deal closed (ISO format)"},"lost_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lost Reason","description":"Why we lost the deal"},"converted_company_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Converted Company Id","description":"Created company record ID"}},"type":"object","title":"ClientReferralUpdate","description":"Update client referral (founder only)"},"CodeCheckIn":{"properties":{"email":{"type":"string","maxLength":320,"minLength":5,"title":"Email"},"code":{"type":"string","pattern":"^\\d{6}$","title":"Code"}},"type":"object","required":["email","code"],"title":"CodeCheckIn"},"CodeIn":{"properties":{"email":{"type":"string","maxLength":254,"title":"Email"}},"type":"object","required":["email"],"title":"CodeIn"},"CodeSendIn":{"properties":{"email":{"type":"string","maxLength":320,"minLength":5,"title":"Email"}},"type":"object","required":["email"],"title":"CodeSendIn"},"CommissionResponse":{"properties":{"rep_id":{"type":"string","title":"Rep Id"},"period":{"type":"string","title":"Period"},"placements":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Placements"},"total_revenue":{"type":"number","title":"Total Revenue"},"commission_rate":{"type":"number","title":"Commission Rate"},"commission_amount":{"type":"number","title":"Commission Amount"},"first_placement_bonus":{"type":"number","title":"First Placement Bonus"},"total_payout":{"type":"number","title":"Total Payout"}},"type":"object","required":["rep_id","period","placements","total_revenue","commission_rate","commission_amount","first_placement_bonus","total_payout"],"title":"CommissionResponse"},"CompanyCreate":{"properties":{"company_name":{"type":"string","maxLength":255,"title":"Company Name","description":"Legal entity name"},"domain":{"type":"string","maxLength":255,"title":"Domain","description":"Company domain (e.g. acme.com)"},"website":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Website","description":"Company website"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"company_size":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Size"},"billing_email":{"type":"string","format":"email","title":"Billing Email","description":"Invoice recipient email"},"billing_address":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Address","description":"Billing address"},"signer_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Signer Name","description":"Contract signer full name"},"signer_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Signer Email","description":"Contract signer email (defaults to billing_email)"},"pricing_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pricing Tier","description":"Pricing tier","default":"Pilot"},"service_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Type","description":"staffing or factory","default":"staffing"},"first_project":{"anyOf":[{"$ref":"#/components/schemas/FirstProjectCreate"},{"type":"null"}],"description":"Optional first project to create with the company"}},"type":"object","required":["company_name","domain","billing_email"],"title":"CompanyCreate","description":"Request model for creating a company"},"CompanyListResponse":{"properties":{"companies":{"items":{"$ref":"#/components/schemas/CompanyResponse"},"type":"array","title":"Companies"},"total":{"type":"integer","title":"Total"},"page":{"type":"integer","title":"Page"},"per_page":{"type":"integer","title":"Per Page"}},"type":"object","required":["companies","total","page","per_page"],"title":"CompanyListResponse","description":"Response model for paginated company list"},"CompanyRedaction":{"properties":{"original":{"type":"string","title":"Original"},"redacted":{"type":"string","title":"Redacted"},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role"},"index":{"type":"integer","minimum":0.0,"title":"Index"}},"type":"object","required":["original","redacted","index"],"title":"CompanyRedaction","description":"One redacted past-company entry."},"CompanyResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Record ID"},"company_name":{"type":"string","title":"Company Name"},"domain":{"type":"string","title":"Domain"},"website":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Website"},"industry":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Industry"},"company_size":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Size"},"billing_email":{"type":"string","title":"Billing Email"},"billing_address":{"type":"string","title":"Billing Address"},"signer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signer Name"},"signer_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signer Email"},"stripe_customer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Customer Id"},"pricing_tier":{"type":"string","title":"Pricing Tier"},"total_active_seats":{"type":"integer","title":"Total Active Seats","default":0},"status":{"type":"string","title":"Status","default":"Active"},"signed_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Signed Date"},"nps_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nps Score"},"slack_channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Slack Channel"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_activity":{"type":"string","format":"date-time","title":"Last Activity"}},"type":"object","required":["id","company_name","domain","billing_email","billing_address","pricing_tier","created_at","last_activity"],"title":"CompanyResponse","description":"Response model for company data"},"CompanyUpdate":{"properties":{"company_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Company Name"},"website":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Website"},"industry":{"anyOf":[{"type":"string","enum":["SaaS","FinTech","AI/ML","E-commerce","Other"]},{"type":"null"}],"title":"Industry"},"company_size":{"anyOf":[{"type":"string","enum":["1-50","51-200","201-500","500+"]},{"type":"null"}],"title":"Company Size"},"billing_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Billing Email"},"billing_address":{"anyOf":[{"type":"string","minLength":10},{"type":"null"}],"title":"Billing Address"},"signer_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Signer Name"},"signer_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Signer Email"},"pricing_tier":{"anyOf":[{"type":"string","enum":["Pilot","Growth","Squad"]},{"type":"null"}],"title":"Pricing Tier"},"status":{"anyOf":[{"type":"string","enum":["Active","Churned","Paused"]},{"type":"null"}],"title":"Status"},"nps_score":{"anyOf":[{"type":"integer","maximum":10.0,"minimum":1.0},{"type":"null"}],"title":"Nps Score","description":"NPS score 1-10"}},"type":"object","title":"CompanyUpdate","description":"Request model for updating a company"},"ConfirmIn":{"properties":{"email":{"type":"string","maxLength":254,"title":"Email"},"code":{"anyOf":[{"type":"string","maxLength":12},{"type":"null"}],"title":"Code"},"verification_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Verification Id"}},"type":"object","required":["email"],"title":"ConfirmIn"},"ConsentIn":{"properties":{"accepted":{"type":"boolean","title":"Accepted"},"bench_opt_in":{"type":"boolean","title":"Bench Opt In","default":false},"browser_key":{"anyOf":[{"type":"string","maxLength":128},{"type":"null"}],"title":"Browser Key"},"send_copy":{"type":"boolean","title":"Send Copy","default":false}},"type":"object","required":["accepted"],"title":"ConsentIn"},"ConsumeIn":{"properties":{"token":{"type":"string","maxLength":200,"title":"Token"},"user_agent":{"anyOf":[{"type":"string","maxLength":400},{"type":"null"}],"title":"User Agent"}},"type":"object","required":["token"],"title":"ConsumeIn"},"ContractorPaymentCreate":{"properties":{"placement_id":{"type":"string","title":"Placement Id"},"billing_period":{"type":"string","pattern":"^\\d{4}-\\d{2}$","title":"Billing Period"},"contractor_cost_dollars":{"type":"integer","exclusiveMinimum":0.0,"title":"Contractor Cost Dollars"},"provider_fee_cents":{"type":"integer","minimum":0.0,"title":"Provider Fee Cents","default":4900},"payment_provider":{"type":"string","title":"Payment Provider","default":"deel"},"provider_payment_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Provider Payment Id"}},"type":"object","required":["placement_id","billing_period","contractor_cost_dollars"],"title":"ContractorPaymentCreate"},"Conversation":{"properties":{"id":{"type":"string","title":"Id"},"participant_name":{"type":"string","title":"Participant Name"},"participant_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Participant Url"},"participant_headline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Participant Headline"},"last_message":{"type":"string","title":"Last Message"},"last_message_time":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Message Time"},"unread":{"type":"boolean","title":"Unread","default":false},"unread_count":{"type":"integer","title":"Unread Count","default":0},"account_id":{"type":"string","title":"Account Id","default":"acc1"},"candidate_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Candidate Id"}},"type":"object","required":["id","participant_name","last_message"],"title":"Conversation"},"ConversationPatch":{"properties":{"user_id":{"type":"string","title":"User Id"},"title":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Title"},"archived":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Archived"}},"type":"object","required":["user_id"],"title":"ConversationPatch"},"ConvertReferralRequest":{"properties":{"referral_id":{"type":"string","title":"Referral Id","description":"Candidate referral ID to convert"},"additional_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Additional Notes","description":"Additional notes for candidate record"}},"type":"object","required":["referral_id"],"title":"ConvertReferralRequest","description":"Request to convert referral to candidate"},"ConvertReferralResponse":{"properties":{"referral_id":{"type":"string","title":"Referral Id"},"candidate_id":{"type":"string","title":"Candidate Id"},"candidate_name":{"type":"string","title":"Candidate Name"},"overall_score":{"type":"integer","title":"Overall Score","description":"Candidate score from scoring service"},"status":{"type":"string","title":"Status","description":"New referral status"},"message":{"type":"string","title":"Message","description":"Confirmation message"}},"type":"object","required":["referral_id","candidate_id","candidate_name","overall_score","status","message"],"title":"ConvertReferralResponse","description":"Response after converting referral to candidate"},"ConvertToCompanyRequest":{"properties":{"billing_address":{"type":"string","title":"Billing Address","description":"Company billing address"},"additional_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Additional Notes","description":"Additional onboarding notes"}},"type":"object","required":["billing_address"],"title":"ConvertToCompanyRequest","description":"Request to convert referral to company"},"ConvertToCompanyResponse":{"properties":{"referral_id":{"type":"string","title":"Referral Id"},"company_id":{"type":"string","title":"Company Id"},"company_name":{"type":"string","title":"Company Name"},"stripe_customer_id":{"type":"string","title":"Stripe Customer Id"},"reward_amount":{"type":"number","title":"Reward Amount"},"reward_tier":{"type":"string","title":"Reward Tier"},"message":{"type":"string","title":"Message"}},"type":"object","required":["referral_id","company_id","company_name","stripe_customer_id","reward_amount","reward_tier","message"],"title":"ConvertToCompanyResponse","description":"Response after converting referral to company"},"CorrectionIn":{"properties":{"category":{"type":"string","title":"Category"},"value":{"type":"string","maxLength":300,"minLength":1,"title":"Value"},"role_scope":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Role Scope"},"replaces":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Replaces"}},"type":"object","required":["category","value"],"title":"CorrectionIn"},"CreateCampaignRequest":{"properties":{"name":{"type":"string","title":"Name"},"campaign_type":{"type":"string","title":"Campaign Type"},"target_persona":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Persona"},"connection_template":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connection Template"},"message_template":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Template"},"followup_template":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Followup Template"},"message_delay_hours":{"type":"integer","title":"Message Delay Hours","default":24},"followup_delay_days":{"type":"integer","title":"Followup Delay Days","default":7},"max_followups":{"type":"integer","title":"Max Followups","default":1},"auto_approve_threshold":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Approve Threshold"},"linkedin_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Account Id"}},"type":"object","required":["name","campaign_type"],"title":"CreateCampaignRequest"},"CvAlumniCandidate":{"properties":{"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"entries_hash":{"type":"string","title":"Entries Hash"},"prompt_version":{"type":"integer","title":"Prompt Version","default":1},"model":{"type":"string","title":"Model"},"mentions":{"items":{"$ref":"#/components/schemas/CvAlumniMention"},"type":"array","maxItems":60,"title":"Mentions"}},"type":"object","required":["candidate_id","entries_hash","model"],"title":"CvAlumniCandidate"},"CvAlumniMention":{"properties":{"entry_index":{"type":"integer","title":"Entry Index"},"role":{"type":"string","title":"Role"},"company_name":{"type":"string","title":"Company Name"},"company_key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Key"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"label":{"type":"string","title":"Label"},"via_company":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Via Company"},"ended":{"type":"boolean","title":"Ended","default":false},"stack":{"items":{"type":"string"},"type":"array","title":"Stack"}},"type":"object","required":["entry_index","role","company_name","label"],"title":"CvAlumniMention"},"CvAlumniMentionsRequest":{"properties":{"candidates":{"items":{"$ref":"#/components/schemas/CvAlumniCandidate"},"type":"array","maxItems":200,"minItems":1,"title":"Candidates"}},"type":"object","required":["candidates"],"title":"CvAlumniMentionsRequest"},"DashboardResponse":{"properties":{"pages_live":{"type":"integer","title":"Pages Live"},"leads_attributed_30d":{"type":"integer","title":"Leads Attributed 30D"},"avg_judge_score_30d":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Avg Judge Score 30D"},"regen_failure_rate_30d":{"type":"number","title":"Regen Failure Rate 30D"},"canary_organic_clicks_7d":{"type":"integer","title":"Canary Organic Clicks 7D"}},"type":"object","required":["pages_live","leads_attributed_30d","avg_judge_score_30d","regen_failure_rate_30d","canary_organic_clicks_7d"],"title":"DashboardResponse","description":"The 5 numbers Roberto checks every Friday."},"DealCloseRequest":{"properties":{"closed_won":{"type":"boolean","title":"Closed Won"},"deal_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Deal Value"},"lost_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lost Reason"}},"type":"object","required":["closed_won"],"title":"DealCloseRequest","description":"Close a deal — won or lost. Lost requires a loss reason."},"DealStageUpdate":{"properties":{"stage":{"type":"string","pattern":"^(prospecting|qualified|discovery|proposal|interview|contract|closedwon|closedlost)$","title":"Stage","description":"Pipeline stage"},"deal_value":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Deal Value","description":"Expected monthly revenue"}},"type":"object","required":["stage"],"title":"DealStageUpdate"},"DecisionRequest":{"properties":{"approve":{"type":"boolean","title":"Approve"},"notes":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Notes"}},"type":"object","required":["approve"],"title":"DecisionRequest","description":"`approve` is explicit rather than a status string — there are exactly\ntwo outcomes and a free-text status is how typos become new statuses."},"DeelContractCreate":{"properties":{"placement_id":{"type":"string","title":"Placement Id"},"contractor_name":{"type":"string","title":"Contractor Name"},"contractor_email":{"type":"string","title":"Contractor Email"},"job_title":{"type":"string","title":"Job Title"},"monthly_rate_dollars":{"type":"integer","exclusiveMinimum":0.0,"title":"Monthly Rate Dollars"},"currency":{"type":"string","title":"Currency","default":"USD"},"start_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Start Date"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"}},"type":"object","required":["placement_id","contractor_name","contractor_email","job_title","monthly_rate_dollars"],"title":"DeelContractCreate"},"DemoCompletedRequest":{"properties":{"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","title":"DemoCompletedRequest","description":"Optional notes when logging demo completion."},"DiscountRedeemRequest":{"properties":{"deal_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deal Id"}},"type":"object","title":"DiscountRedeemRequest"},"DiscountRedeemResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"code":{"type":"string","title":"Code"},"used_at":{"type":"string","format":"date-time","title":"Used At"},"lead_id":{"type":"string","title":"Lead Id"}},"type":"object","required":["success","code","used_at","lead_id"],"title":"DiscountRedeemResponse"},"DiscountReportResponse":{"properties":{"window_days":{"type":"integer","title":"Window Days"},"issued":{"type":"integer","title":"Issued"},"redeemed":{"type":"integer","title":"Redeemed"},"expired_unused":{"type":"integer","title":"Expired Unused"},"redemption_rate":{"type":"number","title":"Redemption Rate"},"by_temp_band":{"additionalProperties":true,"type":"object","title":"By Temp Band"},"by_variant":{"additionalProperties":true,"type":"object","title":"By Variant"}},"type":"object","required":["window_days","issued","redeemed","expired_unused","redemption_rate","by_temp_band","by_variant"],"title":"DiscountReportResponse"},"DiscountValidateResponse":{"properties":{"valid":{"type":"boolean","title":"Valid"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"},"code":{"type":"string","title":"Code"},"lead_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Id"},"lead_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Email"},"lead_company":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Company"},"lead_first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead First Name"},"temp_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Temp Score"},"expires_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Expires At"},"used_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Used At"}},"type":"object","required":["valid","code"],"title":"DiscountValidateResponse"},"DocumentCreate":{"properties":{"entity_type":{"type":"string","pattern":"^(candidate|company|placement|project)$","title":"Entity Type"},"entity_id":{"type":"string","title":"Entity Id"},"doc_type":{"type":"string","pattern":"^(resume|portfolio|certification|nda|right_to_work|other)$","title":"Doc Type"},"title":{"type":"string","maxLength":255,"title":"Title"},"file_url":{"type":"string","maxLength":1000,"title":"File Url"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["entity_type","entity_id","doc_type","title","file_url"],"title":"DocumentCreate"},"DocumentUpdate":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Title"},"file_url":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"File Url"},"doc_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doc Type"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","title":"DocumentUpdate"},"EligibleCandidateView":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"target_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Role"},"cv_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cv Score"},"interview_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Interview Score"},"interview_completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Interview Completed At"}},"type":"object","required":["id","name","email","target_role","cv_score","interview_score","interview_completed_at"],"title":"EligibleCandidateView","description":"One row in the live-screen-queue list. Used by the bulk-send UI."},"EligibleEngineer":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"overall_score":{"type":"integer","title":"Overall Score"},"skills":{"items":{"type":"string"},"type":"array","title":"Skills"},"current_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Role"},"is_seo_excluded":{"type":"boolean","title":"Is Seo Excluded"}},"type":"object","required":["id","name","overall_score","skills","current_role","is_seo_excluded"],"title":"EligibleEngineer"},"EmailBody":{"properties":{"read_id":{"type":"string","format":"uuid","title":"Read Id"},"email":{"type":"string","format":"email","title":"Email"},"first_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"First Name"}},"type":"object","required":["read_id","email"],"title":"EmailBody"},"EnrichBatchRequest":{"properties":{"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","default":20},"dry_run":{"type":"boolean","title":"Dry Run","default":false}},"type":"object","title":"EnrichBatchRequest"},"EnrichBatchResponse":{"properties":{"considered":{"type":"integer","title":"Considered"},"enriched":{"type":"integer","title":"Enriched"},"failed":{"type":"integer","title":"Failed"},"skipped_low_score":{"type":"integer","title":"Skipped Low Score"},"hold_no_signal":{"type":"integer","title":"Hold No Signal"},"total_cost_cents":{"type":"integer","title":"Total Cost Cents"},"kill_switch_off":{"type":"boolean","title":"Kill Switch Off"},"budget_exhausted":{"type":"boolean","title":"Budget Exhausted"},"dry_run":{"type":"boolean","title":"Dry Run"}},"type":"object","required":["considered","enriched","failed","skipped_low_score","hold_no_signal","total_cost_cents","kill_switch_off","budget_exhausted","dry_run"],"title":"EnrichBatchResponse"},"EnrichLeadResponse":{"properties":{"lead_id":{"type":"string","title":"Lead Id"},"status":{"type":"string","title":"Status"},"score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Score"},"urgency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Urgency"},"primary_signal":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Primary Signal"},"ai_opener":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Opener"},"cost_cents":{"type":"integer","title":"Cost Cents","default":0},"prompt_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Prompt Version"},"signals_summary":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Signals Summary","description":"which providers returned data (true) vs skipped/failed (false)"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"}},"type":"object","required":["lead_id","status"],"title":"EnrichLeadResponse"},"EnrichLeadsRequest":{"properties":{"full_name":{"type":"string","title":"Full Name"},"company_name":{"type":"string","title":"Company Name"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"mode":{"type":"string","title":"Mode","description":"staff-aug or factory","default":"staff-aug"}},"type":"object","required":["full_name","company_name"],"title":"EnrichLeadsRequest"},"EnrichmentStateResponse":{"properties":{"lead_id":{"type":"string","title":"Lead Id"},"enrichment_status":{"type":"string","title":"Enrichment Status"},"enriched_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enriched At"},"ai_opener":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Opener"},"enrichment_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Enrichment Score"},"enrichment_urgency":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enrichment Urgency"},"enrichment_primary_signal":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enrichment Primary Signal"},"enrichment_prompt_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enrichment Prompt Version"},"enrichment_cost_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Enrichment Cost Cents"},"enrichment_attempts":{"type":"integer","title":"Enrichment Attempts","default":0},"enrichment_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Enrichment Error"},"signals":{"additionalProperties":true,"type":"object","title":"Signals"},"provider_data":{"additionalProperties":true,"type":"object","title":"Provider Data"}},"type":"object","required":["lead_id","enrichment_status"],"title":"EnrichmentStateResponse"},"EscalatePayload":{"properties":{"slug":{"type":"string","title":"Slug"},"keyword":{"type":"string","title":"Keyword"},"cluster":{"type":"string","title":"Cluster"},"attempt":{"type":"integer","title":"Attempt"},"aggregate_score":{"type":"integer","title":"Aggregate Score"},"per_judge_scores":{"additionalProperties":{"type":"integer"},"type":"object","title":"Per Judge Scores"},"veto_reasons":{"items":{"type":"string"},"type":"array","title":"Veto Reasons"},"regen_hints":{"items":{"type":"string"},"type":"array","title":"Regen Hints"},"run_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Run Id"}},"type":"object","required":["slug","keyword","cluster","attempt","aggregate_score","per_judge_scores"],"title":"EscalatePayload"},"FactPatch":{"properties":{"action":{"type":"string","enum":["confirm","dispute","edit"],"title":"Action"},"value":{"anyOf":[{"type":"string","maxLength":300,"minLength":1},{"type":"null"}],"title":"Value"},"role_scope":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Role Scope"}},"type":"object","required":["action"],"title":"FactPatch"},"FactoryDeliverableCreate":{"properties":{"title":{"type":"string","maxLength":255,"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"deliverable_type":{"type":"string","title":"Deliverable Type","description":"code|design|document|deployment|demo_video","default":"code"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url"}},"type":"object","required":["title"],"title":"FactoryDeliverableCreate"},"FactoryInquiryCreate":{"properties":{"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"utm_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Content"},"utm_term":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Term"},"referrer_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Url"},"landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Landing Page"},"first_touch_landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Touch Landing Page"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"mcp_client":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mcp Client"},"mcp_client_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Mcp Client Metadata"},"name":{"type":"string","title":"Name"},"email":{"type":"string","format":"email","title":"Email"},"company":{"type":"string","title":"Company"},"description":{"type":"string","title":"Description"},"budget":{"type":"string","title":"Budget","default":""},"timeline":{"type":"string","title":"Timeline","default":""}},"type":"object","required":["name","email","company","description"],"title":"FactoryInquiryCreate","description":"Factory project inquiry from the factory page form."},"FactoryMilestoneCreate":{"properties":{"milestone_number":{"type":"integer","minimum":1.0,"title":"Milestone Number"},"title":{"type":"string","maxLength":255,"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"acceptance_criteria":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acceptance Criteria"},"price_cents":{"type":"integer","minimum":0.0,"title":"Price Cents","default":0},"due_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Due Date"}},"type":"object","required":["milestone_number","title"],"title":"FactoryMilestoneCreate"},"FactoryMilestoneUpdate":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"acceptance_criteria":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Acceptance Criteria"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"price_cents":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Price Cents"},"due_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Due Date"},"staging_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Staging Url"},"reviewer_notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reviewer Notes"}},"type":"object","title":"FactoryMilestoneUpdate"},"FactoryProjectCreate":{"properties":{"company_id":{"type":"string","title":"Company Id","description":"Client company ID"},"title":{"type":"string","maxLength":255,"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"tech_stack":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tech Stack"},"total_price_cents":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Total Price Cents"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"target_delivery_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Target Delivery Date"},"staging_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Staging Url"},"production_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Production Url"},"repo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Url"},"assigned_pm_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned Pm Id"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"billing_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Model","description":"monthly|milestone|split","default":"monthly"},"monthly_rate_cents":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Monthly Rate Cents"},"payment_schedule":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Schedule","description":"JSON for split billing model"}},"type":"object","required":["company_id","title"],"title":"FactoryProjectCreate"},"FactoryProjectUpdate":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"tech_stack":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tech Stack"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"total_price_cents":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Total Price Cents"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"target_delivery_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Target Delivery Date"},"actual_delivery_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Actual Delivery Date"},"staging_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Staging Url"},"production_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Production Url"},"repo_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Repo Url"},"assigned_pm_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned Pm Id"},"contract_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Contract Id"},"sow_contract_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sow Contract Id"},"maintenance_contract_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Maintenance Contract Id"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"billing_model":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Billing Model","description":"monthly|milestone|split"},"monthly_rate_cents":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Monthly Rate Cents"},"payment_schedule":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Schedule","description":"JSON for split billing model"}},"type":"object","title":"FactoryProjectUpdate"},"FactoryUpdateCreate":{"properties":{"update_type":{"type":"string","title":"Update Type","description":"progress|milestone_submitted|milestone_accepted|milestone_rejected|general","default":"progress"},"title":{"type":"string","maxLength":255,"title":"Title"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"is_client_visible":{"type":"boolean","title":"Is Client Visible","default":true}},"type":"object","required":["title"],"title":"FactoryUpdateCreate"},"FeatureToggle":{"properties":{"feature":{"type":"string","title":"Feature"},"enabled":{"type":"boolean","title":"Enabled"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"}},"type":"object","required":["feature","enabled"],"title":"FeatureToggle"},"FirstProjectCreate":{"properties":{"title":{"type":"string","maxLength":255,"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"tech_stack":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tech Stack"},"seniority_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seniority Level"},"headcount":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Headcount","default":1},"monthly_rate_min":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Monthly Rate Min"},"monthly_rate_max":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Monthly Rate Max"},"priority":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Priority","default":"Medium"},"deadline":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Deadline"},"location_preference":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location Preference"},"budget":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Budget","description":"Total budget for factory"},"timeline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timeline","description":"Delivery timeline for factory"}},"type":"object","required":["title"],"title":"FirstProjectCreate","description":"Optional first project to create alongside the company"},"FitReasoning":{"properties":{"strengths":{"items":{"type":"string"},"type":"array","title":"Strengths"},"concerns":{"items":{"type":"string"},"type":"array","title":"Concerns"},"summary":{"type":"string","title":"Summary"}},"type":"object","required":["summary"],"title":"FitReasoning","description":"Claude's structured rationale. Stored as JSONB on candidate_fit_scores."},"FitScoreResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"project_id":{"type":"string","format":"uuid","title":"Project Id"},"score":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Score"},"reasoning":{"$ref":"#/components/schemas/FitReasoning"},"model_version":{"type":"string","title":"Model Version"},"prompt_version":{"type":"integer","title":"Prompt Version"},"scored_at":{"type":"string","format":"date-time","title":"Scored At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"cached":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Cached"}},"type":"object","required":["id","candidate_id","project_id","score","reasoning","model_version","prompt_version","scored_at","created_at"],"title":"FitScoreResponse","description":"Returned by POST /api/candidates/{id}/score-for-project/{project_id}\nand the per-row entries in GET /api/projects/{id}/ranked-candidates.\n\nBoth code paths share this schema so the frontend doesn't need to branch."},"FormSubmissionCreate":{"properties":{"first_name":{"type":"string","maxLength":120,"title":"First Name"},"last_name":{"type":"string","maxLength":120,"title":"Last Name"},"email":{"type":"string","format":"email","title":"Email"},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"resume_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resume Url"},"role_category":{"type":"string","title":"Role Category"},"source":{"type":"string","title":"Source","default":"ruzora_form"},"job_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Slug"},"message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message"},"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"utm_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Content"},"utm_term":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Term"},"referrer_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Url"},"first_touch_landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Touch Landing Page"},"ref":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Ref"}},"type":"object","required":["first_name","last_name","email","role_category"],"title":"FormSubmissionCreate","description":"Schema for creating a new form submission via API."},"FormSubmissionResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"candidate_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Candidate Id"},"message":{"type":"string","title":"Message"},"profile_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Url"},"retry_from":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Retry From"},"challenge_pending":{"type":"boolean","title":"Challenge Pending","default":false},"resume_upload_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resume Upload Token"}},"type":"object","required":["success","message"],"title":"FormSubmissionResponse","description":"Response schema for form submission."},"GenerateRequest":{"properties":{"candidate_name":{"type":"string","title":"Candidate Name"},"location":{"type":"string","title":"Location"},"skills":{"items":{"type":"string"},"type":"array","title":"Skills"},"current_role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Role"},"company":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company"},"context":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Context"}},"type":"object","required":["candidate_name","location","skills"],"title":"GenerateRequest"},"GenerateResponse":{"properties":{"alternatives":{"items":{"$ref":"#/components/schemas/MessageAlternative"},"type":"array","title":"Alternatives"}},"type":"object","required":["alternatives"],"title":"GenerateResponse"},"GenerationRunRow":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"slug":{"type":"string","title":"Slug"},"cluster":{"type":"string","title":"Cluster"},"keyword":{"type":"string","title":"Keyword"},"attempt":{"type":"integer","title":"Attempt"},"status":{"type":"string","title":"Status"},"aggregate_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Aggregate Score"},"queued_at":{"type":"string","format":"date-time","title":"Queued At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"per_judge_scores":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Per Judge Scores"}},"type":"object","required":["id","slug","cluster","keyword","attempt","status","aggregate_score","queued_at","completed_at"],"title":"GenerationRunRow"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HiringLeadCreate":{"properties":{"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"utm_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Content"},"utm_term":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Term"},"referrer_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Url"},"landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Landing Page"},"first_touch_landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Touch Landing Page"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"mcp_client":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Mcp Client"},"mcp_client_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Mcp Client Metadata"},"name":{"type":"string","title":"Name"},"email":{"type":"string","format":"email","title":"Email"},"phone":{"type":"string","title":"Phone","default":""},"company_name":{"type":"string","title":"Company Name"},"company_domain":{"type":"string","title":"Company Domain","default":""},"hiring_need":{"type":"string","maxLength":4000,"title":"Hiring Need","default":""}},"type":"object","required":["name","email","company_name"],"title":"HiringLeadCreate","description":"Hiring lead from the home page form."},"ImportRequest":{"properties":{"candidates":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Candidates"},"auto_score":{"type":"boolean","title":"Auto Score","default":true}},"type":"object","required":["candidates"],"title":"ImportRequest","description":"Request to import specific candidates"},"InterviewAssessmentCreate":{"properties":{"format":{"type":"string","enum":["system_design","code_review","project_walk"],"title":"Format"},"tech_score":{"anyOf":[{"type":"number","maximum":5.0,"minimum":1.0},{"type":"string"}],"title":"Tech Score"},"comm_score":{"anyOf":[{"type":"number","maximum":5.0,"minimum":1.0},{"type":"string"}],"title":"Comm Score"},"culture_score":{"anyOf":[{"type":"number","maximum":5.0,"minimum":1.0},{"type":"string"}],"title":"Culture Score"},"motivation_score":{"anyOf":[{"type":"number","maximum":5.0,"minimum":1.0},{"type":"string"}],"title":"Motivation Score"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"decision":{"type":"string","enum":["pass","fail","strong_pass"],"title":"Decision"}},"type":"object","required":["format","tech_score","comm_score","culture_score","motivation_score","decision"],"title":"InterviewAssessmentCreate","description":"Payload for POST /api/candidates/{id}/interview."},"InterviewAssessmentResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"interviewer_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Interviewer Id"},"format":{"type":"string","title":"Format"},"tech_score":{"type":"string","title":"Tech Score"},"comm_score":{"type":"string","title":"Comm Score"},"culture_score":{"type":"string","title":"Culture Score"},"motivation_score":{"type":"string","title":"Motivation Score"},"weighted_total":{"type":"string","title":"Weighted Total"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"decision":{"type":"string","title":"Decision"},"recorded_at":{"type":"string","format":"date-time","title":"Recorded At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"}},"type":"object","required":["id","candidate_id","interviewer_id","format","tech_score","comm_score","culture_score","motivation_score","weighted_total","notes","decision","recorded_at","created_at","updated_at"],"title":"InterviewAssessmentResponse","description":"Returned by all interview endpoints."},"InterviewAssessmentUpdate":{"properties":{"format":{"anyOf":[{"type":"string","enum":["system_design","code_review","project_walk"]},{"type":"null"}],"title":"Format"},"tech_score":{"anyOf":[{"type":"number","maximum":5.0,"minimum":1.0},{"type":"string"},{"type":"null"}],"title":"Tech Score"},"comm_score":{"anyOf":[{"type":"number","maximum":5.0,"minimum":1.0},{"type":"string"},{"type":"null"}],"title":"Comm Score"},"culture_score":{"anyOf":[{"type":"number","maximum":5.0,"minimum":1.0},{"type":"string"},{"type":"null"}],"title":"Culture Score"},"motivation_score":{"anyOf":[{"type":"number","maximum":5.0,"minimum":1.0},{"type":"string"},{"type":"null"}],"title":"Motivation Score"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"decision":{"anyOf":[{"type":"string","enum":["pass","fail","strong_pass"]},{"type":"null"}],"title":"Decision"}},"type":"object","title":"InterviewAssessmentUpdate","description":"Payload for PATCH /api/interviews/{id}. All fields optional."},"InterviewQuestionPayload":{"properties":{"id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Id"},"question_text":{"type":"string","maxLength":2000,"minLength":4,"title":"Question Text"},"time_limit_seconds":{"type":"integer","maximum":600.0,"minimum":15.0,"title":"Time Limit Seconds","default":90},"order_index":{"type":"integer","maximum":20.0,"minimum":0.0,"title":"Order Index"}},"type":"object","required":["question_text","order_index"],"title":"InterviewQuestionPayload","description":"Used for both create (no id) and reorder (with id). Frontend sends\nthe full ordered list; backend diffs and replaces."},"InterviewQuestionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"template_id":{"type":"string","format":"uuid","title":"Template Id"},"question_text":{"type":"string","title":"Question Text"},"time_limit_seconds":{"type":"integer","title":"Time Limit Seconds"},"order_index":{"type":"integer","title":"Order Index"}},"type":"object","required":["id","template_id","question_text","time_limit_seconds","order_index"],"title":"InterviewQuestionResponse"},"InterviewResponseRow":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"question_id":{"type":"string","format":"uuid","title":"Question Id"},"question_text":{"type":"string","title":"Question Text"},"video_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Video Url"},"video_duration_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Video Duration Seconds"},"transcript":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript"},"transcript_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transcript Provider"},"ai_score":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Score"},"ai_reasoning":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Ai Reasoning"},"processing_status":{"type":"string","enum":["pending","transcribing","scoring","done","failed"],"title":"Processing Status"},"processing_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Processing Error"},"uploaded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Uploaded At"},"processed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Processed At"},"delivery_metrics":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Delivery Metrics"},"audio_signals":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Audio Signals"}},"type":"object","required":["id","question_id","question_text","video_url","video_duration_seconds","transcript","transcript_provider","ai_score","ai_reasoning","processing_status","processing_error","uploaded_at","processed_at"],"title":"InterviewResponseRow","description":"One question's response, recruiter-side view (includes transcript + scores)."},"InterviewSummary":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"template_id":{"type":"string","format":"uuid","title":"Template Id"},"template_name":{"type":"string","title":"Template Name"},"status":{"type":"string","enum":["sent","in_progress","completed","expired","reviewed"],"title":"Status"},"sent_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Sent At"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"completed_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Completed At"},"overall_ai_score":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Overall Ai Score"}},"type":"object","required":["id","candidate_id","template_id","template_name","status","sent_at","expires_at","completed_at","overall_ai_score"],"title":"InterviewSummary","description":"Lightweight row for list endpoints (no responses, no transcripts)."},"InterviewTemplateCreate":{"properties":{"name":{"type":"string","maxLength":120,"minLength":2,"title":"Name"},"role_type":{"type":"string","maxLength":60,"minLength":2,"title":"Role Type"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"questions":{"items":{"$ref":"#/components/schemas/InterviewQuestionPayload"},"type":"array","maxItems":10,"minItems":1,"title":"Questions"}},"type":"object","required":["name","role_type","questions"],"title":"InterviewTemplateCreate"},"InterviewTemplateResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"role_type":{"type":"string","title":"Role Type"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_active":{"type":"boolean","title":"Is Active"},"created_by":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Created By"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Updated At"},"questions":{"items":{"$ref":"#/components/schemas/InterviewQuestionResponse"},"type":"array","title":"Questions","default":[]}},"type":"object","required":["id","name","role_type","description","is_active","created_by","created_at","updated_at"],"title":"InterviewTemplateResponse"},"InterviewTemplateUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":120,"minLength":2},{"type":"null"}],"title":"Name"},"role_type":{"anyOf":[{"type":"string","maxLength":60,"minLength":2},{"type":"null"}],"title":"Role Type"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"questions":{"anyOf":[{"items":{"$ref":"#/components/schemas/InterviewQuestionPayload"},"type":"array"},{"type":"null"}],"title":"Questions"}},"type":"object","title":"InterviewTemplateUpdate"},"InvoiceCreate":{"properties":{"client_id":{"type":"string","title":"Client Id","description":"Company record ID"},"placement_ids":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Placement Ids","description":"One or more placement IDs"},"billing_period":{"type":"string","pattern":"^[A-Za-z]+ \\d{4}$","title":"Billing Period","description":"e.g., 'February 2026'"},"amount":{"type":"integer","minimum":1.0,"title":"Amount","description":"Total amount in cents"},"due_date":{"type":"string","format":"date","title":"Due Date","description":"Payment due date"}},"type":"object","required":["client_id","placement_ids","billing_period","amount","due_date"],"title":"InvoiceCreate","description":"Request model for creating an invoice"},"InvoiceResponse":{"properties":{"id":{"type":"string","title":"Id"},"invoice_number":{"type":"string","title":"Invoice Number"},"client":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Client"},"placements":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"title":"Placements"},"billing_period":{"type":"string","title":"Billing Period"},"amount":{"type":"integer","title":"Amount"},"status":{"type":"string","title":"Status"},"stripe_invoice_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Invoice Id"},"due_date":{"type":"string","format":"date","title":"Due Date"},"sent_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Sent Date"},"paid_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Paid Date"},"payment_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Method"},"days_overdue":{"type":"integer","title":"Days Overdue","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","invoice_number","billing_period","amount","status","due_date","created_at"],"title":"InvoiceResponse","description":"Response model for invoice data"},"KnownExploriumIdsResponse":{"properties":{"business_ids":{"items":{"type":"string"},"type":"array","title":"Business Ids"},"prospect_ids":{"items":{"type":"string"},"type":"array","title":"Prospect Ids"},"client_domains":{"items":{"type":"string"},"type":"array","title":"Client Domains"},"total_businesses":{"type":"integer","title":"Total Businesses"},"total_prospects":{"type":"integer","title":"Total Prospects"},"total_client_domains":{"type":"integer","title":"Total Client Domains"}},"type":"object","required":["business_ids","prospect_ids","client_domains","total_businesses","total_prospects","total_client_domains"],"title":"KnownExploriumIdsResponse"},"LabelIn":{"properties":{"response_id":{"type":"string","format":"uuid","title":"Response Id"},"cefr":{"type":"string","pattern":"^(A1|A2|B1|B2|C1|C2)$","title":"Cefr"},"client_ready":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Client Ready"},"notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Notes"}},"type":"object","required":["response_id","cefr"],"title":"LabelIn"},"LaunchRequest":{"properties":{"phantom_type":{"type":"string","title":"Phantom Type"},"keywords":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Keywords"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"max_results":{"type":"integer","title":"Max Results","default":100},"account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Id"},"auto_import":{"type":"boolean","title":"Auto Import","default":true},"message_template":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Template"},"campaign_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Campaign Id"}},"type":"object","required":["phantom_type"],"title":"LaunchRequest"},"LeadAssignRequest":{"properties":{"lead_id":{"type":"string","title":"Lead Id"},"rep_id":{"type":"string","title":"Rep Id"}},"type":"object","required":["lead_id","rep_id"],"title":"LeadAssignRequest"},"LeadConvertRequest":{"properties":{"company_name":{"type":"string","maxLength":255,"minLength":1,"title":"Company Name"},"domain":{"type":"string","maxLength":255,"minLength":3,"title":"Domain"},"signer_name":{"type":"string","maxLength":255,"minLength":2,"title":"Signer Name"},"signer_email":{"type":"string","format":"email","title":"Signer Email"},"billing_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Billing Email"},"pricing_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pricing Tier","default":"Pilot"},"service_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Service Type"},"deal_value":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Deal Value"}},"type":"object","required":["company_name","domain","signer_name","signer_email"],"title":"LeadConvertRequest","description":"One-click convert: pre-filled from the lead row, corrected in the\ndialog. Signer fields are REQUIRED here even though CompanyCreate\nallows them empty — inside the convert flow a missing signer means\nthe MSA silently never goes out (auto_send_msa no-ops), which is the\nsilent-failure class this epic exists to kill."},"LeadImportItem":{"properties":{"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"email":{"type":"string","title":"Email"},"company":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company","default":""},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role","default":""},"hiring_need":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hiring Need","default":""},"seats_needed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seats Needed","default":1},"timeline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timeline","default":""},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source","default":"LinkedIn-PhantomBuster"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"}},"type":"object","required":["first_name","last_name","email"],"title":"LeadImportItem"},"LeadImportRequest":{"properties":{"leads":{"items":{"$ref":"#/components/schemas/LeadImportItem"},"type":"array","minItems":1,"title":"Leads"},"source":{"type":"string","title":"Source","default":"LinkedIn-PhantomBuster"},"auto_assign":{"type":"boolean","title":"Auto Assign","default":true}},"type":"object","required":["leads"],"title":"LeadImportRequest"},"LeadImportResult":{"properties":{"total":{"type":"integer","title":"Total"},"created":{"type":"integer","title":"Created"},"skipped_duplicates":{"type":"integer","title":"Skipped Duplicates"},"errors":{"type":"integer","title":"Errors"},"created_ids":{"items":{"type":"string"},"type":"array","title":"Created Ids"},"skipped_emails":{"items":{"type":"string"},"type":"array","title":"Skipped Emails"},"auto_send_enabled":{"type":"boolean","title":"Auto Send Enabled","default":true},"pending_activation_ids":{"items":{"type":"string"},"type":"array","title":"Pending Activation Ids","default":[]}},"type":"object","required":["total","created","skipped_duplicates","errors","created_ids","skipped_emails"],"title":"LeadImportResult"},"LeaderboardEntry":{"properties":{"referrer_name":{"type":"string","title":"Referrer Name"},"referrer_type":{"type":"string","enum":["Client","Candidate"],"title":"Referrer Type"},"company":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company"},"total_referrals":{"type":"integer","title":"Total Referrals"},"total_conversions":{"type":"integer","title":"Total Conversions"},"conversion_rate":{"type":"number","title":"Conversion Rate"},"total_rewards":{"type":"number","title":"Total Rewards"},"tier":{"type":"string","title":"Tier"}},"type":"object","required":["referrer_name","referrer_type","total_referrals","total_conversions","conversion_rate","total_rewards","tier"],"title":"LeaderboardEntry","description":"Single leaderboard entry"},"LinkedInAccountCreate":{"properties":{"name":{"type":"string","title":"Name"},"email":{"type":"string","title":"Email"},"li_at_cookie":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Li At Cookie"},"user_agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Agent"},"account_type":{"type":"string","title":"Account Type","default":"free"}},"type":"object","required":["name","email"],"title":"LinkedInAccountCreate"},"LinkedInAccountUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"li_at_cookie":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Li At Cookie"},"user_agent":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Agent"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"account_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Account Type"}},"type":"object","title":"LinkedInAccountUpdate"},"LinkedInCallbackIn":{"properties":{"state":{"type":"string","maxLength":200,"title":"State"},"code":{"type":"string","maxLength":2000,"title":"Code"},"user_agent":{"anyOf":[{"type":"string","maxLength":400},{"type":"null"}],"title":"User Agent"},"partner_slug":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Partner Slug"}},"type":"object","required":["state","code"],"title":"LinkedInCallbackIn"},"LinkedInStartIn":{"properties":{"redirect_uri":{"type":"string","maxLength":300,"title":"Redirect Uri"},"link_user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Link User Id"},"return_to":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Return To"}},"type":"object","required":["redirect_uri"],"title":"LinkedInStartIn","description":"`anon_id` is no longer accepted (review round 2, N2): anonymous chats\nmove after the round trip through /auth/claim-anon, so no start request,\nhowever it is built, can plant someone's chats in the account that\ncompletes the sign-in. An `anon_id` field sent by an old caller is\nignored (pydantic drops unknown fields)."},"LiveCallBody":{"properties":{"items":{"additionalProperties":{"type":"boolean"},"type":"object","title":"Items"},"outcome":{"type":"string","enum":["pass","concern","fail"],"title":"Outcome"},"note":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Note"}},"type":"object","required":["outcome"],"title":"LiveCallBody"},"LiveScreenMeetingView":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"kind":{"type":"string","title":"Kind"},"status":{"type":"string","title":"Status"},"booking_uid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Booking Uid"},"invited_at":{"type":"string","format":"date-time","title":"Invited At"},"scheduled_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Scheduled At"},"held_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Held At"},"outcome":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Outcome"},"outcome_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Outcome Reason"}},"type":"object","required":["id","candidate_id","kind","status","booking_uid","invited_at","scheduled_at","held_at","outcome","outcome_reason"],"title":"LiveScreenMeetingView","description":"GET /api/candidates/{id}/live-screen-meeting response.\n\n`status` follows the candidate_meetings CHECK constraint:\n    invited | scheduled | held | no_show | cancelled | expired"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"},"remember_me":{"type":"boolean","title":"Remember Me","default":false}},"type":"object","required":["email","password"],"title":"LoginRequest","description":"Login request"},"LoginResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"user":{"additionalProperties":true,"type":"object","title":"User"}},"type":"object","required":["access_token","user"],"title":"LoginResponse","description":"Login response"},"MarketingConsentRequest":{"properties":{"granted":{"type":"boolean","title":"Granted"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},"type":"object","required":["granted"],"title":"MarketingConsentRequest","description":"`granted=False` revokes. There is no way to spell \"un-revoke\"."},"MarketingTaskCreate":{"properties":{"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"task_type":{"type":"string","title":"Task Type"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"},"scheduled_date":{"type":"string","title":"Scheduled Date"},"scheduled_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scheduled Time"},"priority":{"type":"string","title":"Priority","default":"medium"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"task_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Task Metadata"}},"type":"object","required":["title","task_type","scheduled_date"],"title":"MarketingTaskCreate"},"MarketingTaskUpdate":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"completed_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed By"},"scheduled_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scheduled Date"},"scheduled_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scheduled Time"},"priority":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Priority"}},"type":"object","title":"MarketingTaskUpdate"},"McpRoleIn":{"properties":{"work_email":{"type":"string","maxLength":254,"title":"Work Email"},"title":{"type":"string","maxLength":200,"minLength":2,"title":"Title"},"seniority":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Seniority"},"stack":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Stack"},"notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Notes"}},"type":"object","required":["work_email","title"],"title":"McpRoleIn"},"Message":{"properties":{"id":{"type":"string","title":"Id"},"sender":{"type":"string","title":"Sender"},"content":{"type":"string","title":"Content"},"timestamp":{"type":"string","format":"date-time","title":"Timestamp"},"is_from_me":{"type":"boolean","title":"Is From Me"}},"type":"object","required":["id","sender","content","timestamp","is_from_me"],"title":"Message"},"MessageAlternative":{"properties":{"style":{"type":"string","title":"Style"},"message":{"type":"string","title":"Message"},"character_count":{"type":"integer","title":"Character Count"}},"type":"object","required":["style","message","character_count"],"title":"MessageAlternative"},"MoveCandidateStageRequest":{"properties":{"stage":{"type":"string","title":"Stage","description":"Target stage"}},"type":"object","required":["stage"],"title":"MoveCandidateStageRequest"},"MyClientReferralsResponse":{"properties":{"user_name":{"type":"string","title":"User Name"},"total_referrals":{"type":"integer","title":"Total Referrals"},"total_conversions":{"type":"integer","title":"Total Conversions","description":"Referrals that signed"},"total_rewards":{"type":"number","title":"Total Rewards","description":"Lifetime earnings"},"pending_rewards":{"type":"number","title":"Pending Rewards","description":"Pending rewards"},"tier":{"type":"string","title":"Tier","description":"Referrer tier: Bronze, Silver, Gold, Platinum"},"referrals":{"items":{"$ref":"#/components/schemas/ClientReferralListItem"},"type":"array","title":"Referrals"},"next_tier_progress":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Next Tier Progress","description":"Progress to next tier"}},"type":"object","required":["user_name","total_referrals","total_conversions","total_rewards","pending_rewards","tier","referrals"],"title":"MyClientReferralsResponse","description":"User's client referral dashboard"},"MyReferralsResponse":{"properties":{"total_referrals":{"type":"integer","title":"Total Referrals","description":"Total referrals submitted"},"successful_placements":{"type":"integer","title":"Successful Placements","description":"Number of referrals placed"},"total_rewards":{"type":"number","title":"Total Rewards","description":"Lifetime referral earnings"},"pending_rewards":{"type":"number","title":"Pending Rewards","description":"Pending rewards not yet paid"},"referrals":{"items":{"$ref":"#/components/schemas/CandidateReferralListItem"},"type":"array","title":"Referrals","description":"Recent referrals"}},"type":"object","required":["total_referrals","successful_placements","total_rewards","pending_rewards"],"title":"MyReferralsResponse","description":"User's referral dashboard"},"NPSResponse":{"properties":{"placement_id":{"type":"string","title":"Placement Id"},"score":{"type":"integer","title":"Score"},"category":{"type":"string","enum":["Promoter","Passive","Detractor"],"title":"Category"},"comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Comment"},"survey_type":{"type":"string","title":"Survey Type"},"response_date":{"type":"string","format":"date-time","title":"Response Date"},"actions_triggered":{"items":{"type":"string"},"type":"array","title":"Actions Triggered","description":"Actions taken based on score"}},"type":"object","required":["placement_id","score","category","survey_type","response_date"],"title":"NPSResponse","description":"NPS response with calculated category"},"NPSResponseCreate":{"properties":{"placement_id":{"type":"string","title":"Placement Id","description":"Placement ID"},"score":{"type":"integer","maximum":10.0,"minimum":0.0,"title":"Score","description":"NPS score from 0-10"},"comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Comment","description":"Optional feedback comment"},"survey_type":{"type":"string","enum":["30_day","90_day","180_day","annual"],"title":"Survey Type","description":"Which milestone survey this is"},"respondent_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Respondent Email","description":"Email of person responding"},"is_smoke":{"type":"boolean","title":"Is Smoke","description":"Prod-smoke dry-run: validates the placement and returns the category, but writes nothing and pings nobody. Keeps synthetic responses out of real NPS stats.","default":false}},"type":"object","required":["placement_id","score","survey_type"],"title":"NPSResponseCreate","description":"NPS survey response submission"},"NPSStats":{"properties":{"overall_nps":{"type":"number","title":"Overall Nps","description":"NPS score (-100 to 100)"},"total_responses":{"type":"integer","title":"Total Responses"},"promoters":{"type":"integer","title":"Promoters","description":"Count of 9-10 scores"},"passives":{"type":"integer","title":"Passives","description":"Count of 7-8 scores"},"detractors":{"type":"integer","title":"Detractors","description":"Count of 0-6 scores"},"promoter_percentage":{"type":"number","title":"Promoter Percentage"},"passive_percentage":{"type":"number","title":"Passive Percentage"},"detractor_percentage":{"type":"number","title":"Detractor Percentage"},"response_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Response Rate","description":"% of surveys sent that got responses"},"average_score":{"type":"number","title":"Average Score"}},"type":"object","required":["overall_nps","total_responses","promoters","passives","detractors","promoter_percentage","passive_percentage","detractor_percentage","average_score"],"title":"NPSStats","description":"NPS statistics and analytics"},"NPSTrendData":{"properties":{"month":{"type":"string","title":"Month"},"nps_score":{"type":"number","title":"Nps Score"},"response_count":{"type":"integer","title":"Response Count"},"promoters":{"type":"integer","title":"Promoters"},"passives":{"type":"integer","title":"Passives"},"detractors":{"type":"integer","title":"Detractors"}},"type":"object","required":["month","nps_score","response_count","promoters","passives","detractors"],"title":"NPSTrendData","description":"NPS trend over time"},"NewsletterSubscribeCreate":{"properties":{"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"utm_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Content"},"utm_term":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Term"},"referrer_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Url"},"landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Landing Page"},"first_touch_landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Touch Landing Page"},"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"NewsletterSubscribeCreate"},"NoteIn":{"properties":{"text":{"type":"string","maxLength":5000,"minLength":3,"title":"Text"}},"type":"object","required":["text"],"title":"NoteIn"},"OptOutStatus":{"properties":{"already_opted_out":{"type":"boolean","title":"Already Opted Out","default":false},"ok":{"type":"boolean","title":"Ok","default":true}},"type":"object","title":"OptOutStatus","description":"Neutral response — same shape for valid and invalid tokens."},"OutboundAutoSendToggleRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["enabled"],"title":"OutboundAutoSendToggleRequest","description":"Founder-only flip of the global outbound kill switch."},"OwnerIn":{"properties":{"user_id":{"type":"string","title":"User Id"}},"type":"object","required":["user_id"],"title":"OwnerIn"},"PackageQuestionView":{"properties":{"slug":{"type":"string","title":"Slug"},"prompt_md":{"type":"string","title":"Prompt Md"},"category":{"type":"string","title":"Category"},"estimated_minutes":{"type":"integer","title":"Estimated Minutes"},"order_index":{"type":"integer","title":"Order Index"},"question_type":{"type":"string","title":"Question Type","default":"long_text"},"choices":{"anyOf":[{"items":{"$ref":"#/components/schemas/PublicChoice"},"type":"array"},{"type":"null"}],"title":"Choices"},"answer_md":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Answer Md"},"selected_values":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Selected Values"}},"type":"object","required":["slug","prompt_md","category","estimated_minutes","order_index"],"title":"PackageQuestionView","description":"Public — strips the rubric AND the `correct` flag from choices."},"PartnerCreate":{"properties":{"display_name":{"type":"string","maxLength":120,"minLength":1,"title":"Display Name"},"logo":{"anyOf":[{"type":"string","maxLength":140000},{"type":"null"}],"title":"Logo"},"accent_color":{"anyOf":[{"type":"string","maxLength":7},{"type":"null"}],"title":"Accent Color"},"perk_text":{"anyOf":[{"type":"string","maxLength":280},{"type":"null"}],"title":"Perk Text"},"contact_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Contact Email"},"active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Active"},"slug":{"type":"string","maxLength":40,"minLength":2,"title":"Slug"}},"type":"object","required":["display_name","slug"],"title":"PartnerCreate"},"PartnerPatch":{"properties":{"display_name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Display Name"},"logo":{"anyOf":[{"type":"string","maxLength":140000},{"type":"null"}],"title":"Logo"},"accent_color":{"anyOf":[{"type":"string","maxLength":7},{"type":"null"}],"title":"Accent Color"},"perk_text":{"anyOf":[{"type":"string","maxLength":280},{"type":"null"}],"title":"Perk Text"},"contact_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Contact Email"},"active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Active"}},"type":"object","title":"PartnerPatch"},"PasswordResetConfirm":{"properties":{"token":{"type":"string","title":"Token"},"new_password":{"type":"string","title":"New Password"}},"type":"object","required":["token","new_password"],"title":"PasswordResetConfirm","description":"Password reset confirmation"},"PasswordResetRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"PasswordResetRequest","description":"Password reset request"},"PasteBody":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"first_name":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"First Name"},"markdown":{"type":"string","maxLength":20000,"minLength":40,"title":"Markdown"},"referrer_origin":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Referrer Origin"}},"type":"object","required":["email","markdown"],"title":"PasteBody"},"PipelineRequest":{"properties":{"category":{"type":"string","title":"Category"},"limit":{"type":"integer","title":"Limit","default":25},"outreach_limit":{"type":"integer","title":"Outreach Limit","default":10},"message_type":{"type":"string","title":"Message Type","default":"connection"},"template_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Template Id"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"dry_run":{"type":"boolean","title":"Dry Run","default":false},"skip_outreach":{"type":"boolean","title":"Skip Outreach","default":false}},"type":"object","required":["category"],"title":"PipelineRequest","description":"Request model for pipeline execution"},"PipelineResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"searched":{"type":"integer","title":"Searched"},"scored":{"type":"integer","title":"Scored"},"saved":{"type":"integer","title":"Saved"},"qualified":{"type":"integer","title":"Qualified"},"contacted":{"type":"integer","title":"Contacted"},"skipped":{"type":"integer","title":"Skipped"},"errors":{"items":{"type":"string"},"type":"array","title":"Errors"},"dry_run":{"type":"boolean","title":"Dry Run"}},"type":"object","required":["success","searched","scored","saved","qualified","contacted","skipped","errors","dry_run"],"title":"PipelineResponse","description":"Response model for pipeline execution"},"PlacementCreate":{"properties":{"client_id":{"type":"string","title":"Client Id","description":"Company record ID"},"candidate_id":{"type":"string","title":"Candidate Id","description":"Candidate record ID"},"role_type":{"type":"string","maxLength":100,"title":"Role Type","description":"Job role/title"},"monthly_rate":{"type":"integer","minimum":1000.0,"title":"Monthly Rate","description":"Monthly rate in USD (minimum $1,000)"},"pricing_tier":{"anyOf":[{"type":"string","enum":["Pilot","Growth","Squad"]},{"type":"null"}],"title":"Pricing Tier","description":"Auto-inherited from company if not provided"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date","description":"Candidate start date"},"contractor_monthly_cost":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Contractor Monthly Cost","description":"Monthly contractor pay in USD"}},"type":"object","required":["client_id","candidate_id","role_type","monthly_rate"],"title":"PlacementCreate","description":"Request model for creating a placement"},"PlacementNPSHistory":{"properties":{"placement_id":{"type":"string","title":"Placement Id"},"client_name":{"type":"string","title":"Client Name"},"engineer_name":{"type":"string","title":"Engineer Name"},"start_date":{"type":"string","title":"Start Date"},"current_nps":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Current Nps"},"nps_30_day":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nps 30 Day"},"nps_30_day_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Nps 30 Day Date"},"nps_30_day_comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nps 30 Day Comment"},"nps_90_day":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nps 90 Day"},"nps_90_day_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Nps 90 Day Date"},"nps_90_day_comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nps 90 Day Comment"},"nps_180_day":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nps 180 Day"},"nps_180_day_date":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Nps 180 Day Date"},"nps_180_day_comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nps 180 Day Comment"},"trend":{"type":"string","enum":["improving","stable","declining","unknown"],"title":"Trend","default":"unknown"}},"type":"object","required":["placement_id","client_name","engineer_name","start_date"],"title":"PlacementNPSHistory","description":"Complete NPS history for a placement"},"PlacementResponse":{"properties":{"id":{"type":"string","title":"Id"},"client":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Client"},"candidate":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Candidate"},"role_type":{"type":"string","title":"Role Type"},"monthly_rate":{"type":"integer","title":"Monthly Rate"},"pricing_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pricing Tier"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"End Date"},"status":{"type":"string","title":"Status"},"proposal_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Proposal Url"},"signed_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Signed Date"},"first_invoice_paid":{"type":"boolean","title":"First Invoice Paid","default":false},"churn_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Churn Reason"},"nps_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Nps Score"},"duration_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Duration Days"},"contractor_monthly_cost":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Contractor Monthly Cost"},"deel_contract_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Deel Contract Id"},"payment_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Provider"},"gross_margin_dollars":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Gross Margin Dollars"},"margin_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Margin Percent"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","role_type","monthly_rate","status","created_at"],"title":"PlacementResponse","description":"Response model for placement data"},"PlacementUpdate":{"properties":{"status":{"anyOf":[{"type":"string","enum":["Proposed","Signed","Active","Churned"]},{"type":"null"}],"title":"Status"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"end_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"End Date"},"churn_reason":{"anyOf":[{"type":"string","maxLength":1000},{"type":"null"}],"title":"Churn Reason"},"nps_score":{"anyOf":[{"type":"integer","maximum":10.0,"minimum":1.0},{"type":"null"}],"title":"Nps Score"},"contractor_monthly_cost":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Contractor Monthly Cost","description":"Monthly contractor pay in USD (locked after Deel contract)"}},"type":"object","title":"PlacementUpdate","description":"Request model for updating a placement"},"PrefIn":{"properties":{"subscribed":{"type":"boolean","title":"Subscribed"}},"type":"object","required":["subscribed"],"title":"PrefIn"},"ProfileUpdateBody":{"properties":{"availability_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Availability Status"},"available_from":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Available From","description":"YYYY-MM-DD"},"preferred_rate":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Preferred Rate"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"},"skills":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Skills"},"intent_work_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Intent Work Types"},"intent_team_size":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent Team Size"},"intent_engagement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent Engagement"}},"type":"object","title":"ProfileUpdateBody"},"ProfileUpdateRequest":{"properties":{"availability_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Availability Status"},"available_from":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Available From","description":"YYYY-MM-DD"},"preferred_rate":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Preferred Rate"},"timezone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timezone"},"skills":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Skills"},"intent_work_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Intent Work Types"},"intent_team_size":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent Team Size"},"intent_engagement":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent Engagement"}},"type":"object","title":"ProfileUpdateRequest","description":"PATCH body — all optional; unknown fields rejected by the service."},"ProjectCreate":{"properties":{"company_id":{"type":"string","title":"Company Id","description":"Client company ID"},"title":{"type":"string","maxLength":255,"title":"Title","description":"Job title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"tech_stack":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tech Stack"},"seniority_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seniority Level"},"headcount":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Headcount","default":1},"monthly_rate_min":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Monthly Rate Min"},"monthly_rate_max":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Monthly Rate Max"},"pricing_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pricing Tier"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"deadline":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Deadline"},"location_preference":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Location Preference"},"assigned_recruiter_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned Recruiter Id"},"priority":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Priority","default":"Medium"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["company_id","title"],"title":"ProjectCreate"},"ProjectUpdate":{"properties":{"title":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"tech_stack":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tech Stack"},"seniority_level":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Seniority Level"},"headcount":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Headcount"},"monthly_rate_min":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Monthly Rate Min"},"monthly_rate_max":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Monthly Rate Max"},"pricing_tier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pricing Tier"},"start_date":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Start Date"},"deadline":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"title":"Deadline"},"location_preference":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location Preference"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"assigned_recruiter_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assigned Recruiter Id"},"priority":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Priority"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","title":"ProjectUpdate"},"ProviderHealthResponse":{"properties":{"window_days":{"type":"integer","title":"Window Days"},"rows":{"items":{"$ref":"#/components/schemas/ProviderHealthRow"},"type":"array","title":"Rows"}},"type":"object","required":["window_days","rows"],"title":"ProviderHealthResponse"},"ProviderHealthRow":{"properties":{"provider":{"type":"string","title":"Provider"},"fetches":{"type":"integer","title":"Fetches"},"ok":{"type":"integer","title":"Ok"},"ok_rate":{"type":"number","title":"Ok Rate"},"avg_latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Avg Latency Ms"},"p95_latency_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"P95 Latency Ms"},"spend_cents":{"type":"integer","title":"Spend Cents","default":0},"last_error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Error"}},"type":"object","required":["provider","fetches","ok","ok_rate"],"title":"ProviderHealthRow"},"PublicBenchOut":{"properties":{"sufficient":{"type":"boolean","title":"Sufficient"},"available_now":{"type":"null","title":"Available Now"},"minimum_required":{"type":"null","title":"Minimum Required"},"cards":{"items":{"$ref":"#/components/schemas/BenchCardOut"},"type":"array","title":"Cards"},"stacks":{"items":{"$ref":"#/components/schemas/BenchStackOut"},"type":"array","title":"Stacks"},"stack_filters":{"items":{"$ref":"#/components/schemas/BenchStackOut"},"type":"array","title":"Stack Filters"}},"type":"object","required":["sufficient"],"title":"PublicBenchOut","description":"``sufficient=false`` is the self-hiding state: no cards, no chips.\nThe consumer renders a role-request page instead of a bench.\n\nNO ENGINEER NUMBERS (Roberto, 2026-10-10, funnel wave E6): this route is\npublic, so it publishes no bench size, no per-stack counts and no floor.\n``sufficient`` is the only availability signal. The service still\ncomputes the numbers internally (the floor, the self-hiding rule); they\nstop here.\n\nBack-compat for readers built on the old shape:\n  * ``available_now`` and ``minimum_required`` stay as keys and are\n    always ``null`` (every reader already handles null as \"not\n    published\");\n  * ``stacks`` is always ``[]`` (readers that printed per-stack counts\n    print nothing instead of \"undefined\");\n  * the chips moved to ``stack_filters`` (slug + label, no count)."},"PublicChoice":{"properties":{"value":{"type":"string","title":"Value"},"label":{"type":"string","title":"Label"}},"type":"object","required":["value","label"],"title":"PublicChoice","description":"Choice option as the candidate sees it — no `correct` flag."},"PublicInterviewQuestion":{"properties":{"question_id":{"type":"string","format":"uuid","title":"Question Id"},"question_text":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Question Text"},"time_limit_seconds":{"type":"integer","title":"Time Limit Seconds"},"order_index":{"type":"integer","title":"Order Index"},"liveness_prompt":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Liveness Prompt"}},"type":"object","required":["question_id","question_text","time_limit_seconds","order_index"],"title":"PublicInterviewQuestion","description":"What the candidate sees per question. NO server-internal IDs leak\nbeyond the question_id (needed for upload addressing)."},"PublicInterviewView":{"properties":{"interview_id":{"type":"string","format":"uuid","title":"Interview Id"},"candidate_first_name":{"type":"string","title":"Candidate First Name"},"role_type":{"type":"string","title":"Role Type"},"template_name":{"type":"string","title":"Template Name"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"status":{"type":"string","enum":["sent","in_progress","completed","expired","reviewed"],"title":"Status"},"questions":{"items":{"$ref":"#/components/schemas/PublicInterviewQuestion"},"type":"array","title":"Questions"},"uploaded_question_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Uploaded Question Ids","default":[]},"ai_notice_consented":{"type":"boolean","title":"Ai Notice Consented","default":false},"ai_notice_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ai Notice Version"},"training_consent_enabled":{"type":"boolean","title":"Training Consent Enabled","default":false},"training_consented":{"type":"boolean","title":"Training Consented","default":false},"question_gating":{"type":"boolean","title":"Question Gating","default":false},"liveness_checks":{"type":"boolean","title":"Liveness Checks","default":false}},"type":"object","required":["interview_id","candidate_first_name","role_type","template_name","expires_at","status","questions"],"title":"PublicInterviewView","description":"GET /interview/{token} response.\n\nStrictly limited fields — the candidate sees their own first name (for\ngreeting), the role type, the questions, and the expiry. Nothing else."},"PublicQuestionReveal":{"properties":{"question_id":{"type":"string","format":"uuid","title":"Question Id"},"question_text":{"type":"string","title":"Question Text"},"time_limit_seconds":{"type":"integer","title":"Time Limit Seconds"},"order_index":{"type":"integer","title":"Order Index"},"liveness_prompt":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Liveness Prompt"},"revealed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revealed At"}},"type":"object","required":["question_id","question_text","time_limit_seconds","order_index"],"title":"PublicQuestionReveal","description":"POST /interview/{token}/questions/{id}/reveal — one question's text."},"PublicResponseAck":{"properties":{"response_id":{"type":"string","format":"uuid","title":"Response Id"},"question_id":{"type":"string","format":"uuid","title":"Question Id"},"accepted":{"type":"boolean","title":"Accepted"},"next_question_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Next Question Id"},"interview_complete":{"type":"boolean","title":"Interview Complete","default":false}},"type":"object","required":["response_id","question_id","accepted"],"title":"PublicResponseAck","description":"Returned after a successful upload — minimal ack."},"QualifyResponse":{"properties":{"qualified":{"type":"boolean","title":"Qualified"},"redirect_url":{"type":"string","title":"Redirect Url"},"off_ramp_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Off Ramp Reason"},"lead_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Id"},"qualify_band":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Qualify Band"},"qualify_disqualify_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Qualify Disqualify Reason"}},"type":"object","required":["qualified","redirect_url"],"title":"QualifyResponse"},"QualifySubmission":{"properties":{"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"utm_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Content"},"utm_term":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Term"},"referrer_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Url"},"landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Landing Page"},"first_touch_landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Touch Landing Page"},"full_name":{"type":"string","maxLength":200,"minLength":1,"title":"Full Name"},"work_email":{"type":"string","format":"email","title":"Work Email"},"company":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Company"},"intent":{"type":"string","enum":["hire_engineers","build_project","refactor_rescue","researching"],"title":"Intent"},"role_count":{"anyOf":[{"type":"string","enum":["one","two_three","four_plus","not_sure"]},{"type":"null"}],"title":"Role Count"},"budget":{"anyOf":[{"type":"string","enum":["under_15k","15_to_50k","50_to_150k","over_150k","not_sure"]},{"type":"null"}],"title":"Budget"},"runway":{"anyOf":[{"type":"string","enum":["lt_6mo","6_12mo","12_18mo","18_plus_mo","bootstrapped_no_revenue"]},{"type":"null"}],"title":"Runway"},"seat_budget":{"anyOf":[{"type":"string","enum":["lt_4500","4500_5999","6000_7999","8000_plus","not_sure"]},{"type":"null"}],"title":"Seat Budget"},"timing":{"type":"string","enum":["asap","within_month","one_to_three_months","three_plus","no_timeline"],"title":"Timing"},"role":{"type":"string","enum":["founder_ceo","cto_vp_eng","eng_manager","hr_ops_finance","other"],"title":"Role"},"referrer_origin":{"anyOf":[{"type":"string","maxLength":60,"pattern":"^[a-z0-9:_-]{1,60}$"},{"type":"null"}],"title":"Referrer Origin"}},"type":"object","required":["full_name","work_email","intent","timing","role"],"title":"QualifySubmission","description":"Answers from the /qualify wizard. utm_* / referrer / landing pages come\nfrom WebAttributionMixin (www first-touch attribution), truncated never\nrejected."},"QuestionResponseView":{"properties":{"slug":{"type":"string","title":"Slug"},"prompt_md":{"type":"string","title":"Prompt Md"},"category":{"type":"string","title":"Category"},"expected_signal_md":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Expected Signal Md"},"order_index":{"type":"integer","title":"Order Index"},"question_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Question Type"},"choices":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Choices"},"answer_md":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Answer Md"},"selected_values":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Selected Values"},"ai_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ai Score"},"ai_reasoning":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Ai Reasoning"},"responded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Responded At"},"graded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Graded At"}},"type":"object","required":["slug","prompt_md","category","order_index"],"title":"QuestionResponseView","description":"One graded question response — full visibility, recruiter-only."},"RankedCandidate":{"properties":{"fit_score":{"$ref":"#/components/schemas/FitScoreResponse"},"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"candidate_name":{"type":"string","title":"Candidate Name"},"candidate_status":{"type":"string","title":"Candidate Status"},"candidate_location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Candidate Location"},"candidate_skills":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Candidate Skills"},"candidate_archived_reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Candidate Archived Reason"}},"type":"object","required":["fit_score","candidate_id","candidate_name","candidate_status","candidate_location","candidate_skills","candidate_archived_reason"],"title":"RankedCandidate","description":"Row in GET /api/projects/{id}/ranked-candidates — joins fit + candidate."},"RecordAssessmentRequest":{"properties":{"score":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Score","description":"Percentile 0-100 from the provider."},"decision":{"anyOf":[{"type":"string","enum":["passed","failed"]},{"type":"null"}],"title":"Decision","description":"Optional override. If omitted, derived from score (>= PASS_THRESHOLD → passed, else failed)."},"notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Notes"}},"type":"object","required":["score"],"title":"RecordAssessmentRequest","description":"POST /api/candidates/{id}/record-assessment-result\n\nRoberto pastes the percentile score from the provider. We auto-derive\npass/fail from the threshold UNLESS the recruiter overrides — sometimes\nthe provider's percentile lies (test taker copied from ChatGPT, etc.)\nand Roberto needs to fail a \"high\" score manually."},"RecruiterAssessmentView":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"challenge_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Challenge Id"},"assessment_kind":{"type":"string","enum":["coding","questions"],"title":"Assessment Kind","default":"coding"},"challenge_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Challenge Title"},"challenge_language":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Challenge Language"},"challenge_difficulty":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Challenge Difficulty"},"package_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Package Id"},"package_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Package Name"},"package_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Package Slug"},"status":{"type":"string","title":"Status"},"submitted_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Submitted Code"},"test_results":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Test Results"},"score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Score"},"ai_reasoning":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Ai Reasoning"},"sent_at":{"type":"string","format":"date-time","title":"Sent At"},"submitted_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Submitted At"},"graded_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Graded At"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"},"started_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Started At"},"working_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Working Seconds"},"wall_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Wall Seconds"},"time_self_reported":{"type":"boolean","title":"Time Self Reported","default":false},"time_plausible":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Time Plausible"},"question_responses":{"items":{"$ref":"#/components/schemas/QuestionResponseView"},"type":"array","title":"Question Responses","default":[]},"overall_score":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Overall Score"}},"type":"object","required":["id","candidate_id","status","submitted_code","test_results","score","ai_reasoning","sent_at","submitted_at","graded_at","expires_at"],"title":"RecruiterAssessmentView","description":"GET /api/candidates/{id}/coding-assessment — recruiter detail panel."},"RedactCompaniesRequest":{"properties":{"force":{"type":"boolean","title":"Force","description":"Bypass cache + redaction_version match and re-run Claude. Use when the candidate's experience_entries changed but the redaction wasn't invalidated.","default":false}},"type":"object","title":"RedactCompaniesRequest","description":"POST /api/candidates/{id}/redact-companies. Empty body = use defaults."},"RedactCompaniesResponse":{"properties":{"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"current_company_redacted":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Company Redacted"},"past_companies_redacted":{"items":{"$ref":"#/components/schemas/CompanyRedaction"},"type":"array","title":"Past Companies Redacted"},"redaction_version":{"type":"integer","title":"Redaction Version"},"cached":{"type":"boolean","title":"Cached"}},"type":"object","required":["candidate_id","current_company_redacted","past_companies_redacted","redaction_version","cached"],"title":"RedactCompaniesResponse"},"ReferralAnalytics":{"properties":{"total_referrals":{"type":"integer","title":"Total Referrals"},"by_status":{"additionalProperties":true,"type":"object","title":"By Status","description":"Count by status"},"by_referrer_type":{"additionalProperties":true,"type":"object","title":"By Referrer Type","description":"Count by referrer type"},"conversion_rate":{"type":"number","title":"Conversion Rate","description":"Percentage of referrals that got placed"},"avg_quality_score":{"type":"number","title":"Avg Quality Score"},"avg_days_to_conversion":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Days To Conversion"},"total_rewards_paid":{"type":"number","title":"Total Rewards Paid"},"top_referrers":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Top Referrers","description":"Top 10 referrers with counts"}},"type":"object","required":["total_referrals","by_status","by_referrer_type","conversion_rate","avg_quality_score","total_rewards_paid"],"title":"ReferralAnalytics","description":"Referral program analytics (founder only)"},"RefineRequest":{"properties":{"original_message":{"type":"string","title":"Original Message"},"instruction":{"type":"string","title":"Instruction"}},"type":"object","required":["original_message","instruction"],"title":"RefineRequest"},"RefineResponse":{"properties":{"refined_message":{"type":"string","title":"Refined Message"},"changes_made":{"type":"string","title":"Changes Made"}},"type":"object","required":["refined_message","changes_made"],"title":"RefineResponse"},"RefreshCookieRequest":{"properties":{"li_at_cookie":{"type":"string","minLength":20,"title":"Li At Cookie","description":"Fresh li_at cookie value from browser DevTools → Application → Cookies → linkedin.com"},"user_agent":{"type":"string","minLength":20,"title":"User Agent","description":"Browser User-Agent string (run `navigator.userAgent` in DevTools console)"},"phantom_ids":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Phantom Ids","description":"Optional: specific phantoms to sync. Defaults to all known phantoms from env."}},"type":"object","required":["li_at_cookie","user_agent"],"title":"RefreshCookieRequest"},"RefreshCookieResponse":{"properties":{"total":{"type":"integer","title":"Total"},"succeeded":{"type":"integer","title":"Succeeded"},"failed":{"type":"integer","title":"Failed"},"details":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Details"}},"type":"object","required":["total","succeeded","failed","details"],"title":"RefreshCookieResponse"},"ReissueBody":{"properties":{"kind":{"type":"string","title":"Kind"}},"type":"object","required":["kind"],"title":"ReissueBody"},"ReissueIn":{"properties":{"discard":{"type":"boolean","title":"Discard","default":false}},"type":"object","title":"ReissueIn"},"RepStatsResponse":{"properties":{"rep_id":{"type":"string","title":"Rep Id"},"total_leads":{"type":"integer","title":"Total Leads"},"pipeline":{"additionalProperties":true,"type":"object","title":"Pipeline"},"total_placements":{"type":"integer","title":"Total Placements"},"active_placements":{"type":"integer","title":"Active Placements"},"total_mrr":{"type":"integer","title":"Total Mrr"},"activity_counts":{"additionalProperties":true,"type":"object","title":"Activity Counts"}},"type":"object","required":["rep_id","total_leads","pipeline","total_placements","active_placements","total_mrr","activity_counts"],"title":"RepStatsResponse"},"RequestCodeBody":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"RequestCodeBody"},"RequestIn":{"properties":{"email":{"type":"string","maxLength":254,"title":"Email"},"channel":{"type":"string","const":"mcp","title":"Channel","default":"mcp"},"mcp_client":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Mcp Client"},"action_label":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Action Label"}},"type":"object","required":["email"],"title":"RequestIn"},"RequestLinkBody":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"RequestLinkBody"},"ResolveBody":{"properties":{"resolution":{"type":"string","enum":["cleared","confirmed"],"title":"Resolution"},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note"}},"type":"object","required":["resolution"],"title":"ResolveBody"},"RestoreBody":{"properties":{"reason":{"type":"string","maxLength":4000,"minLength":1,"title":"Reason"}},"type":"object","required":["reason"],"title":"RestoreBody"},"ResumeAttachRequest":{"properties":{"resume_url":{"type":"string","maxLength":2048,"minLength":1,"title":"Resume Url"},"resume_upload_token":{"type":"string","maxLength":512,"minLength":1,"title":"Resume Upload Token"},"filename":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Filename"}},"type":"object","required":["resume_url","resume_upload_token"],"title":"ResumeAttachRequest","description":"Body of PATCH /api/forms/submission/{candidate_id}/resume."},"ResumeAttachResponse":{"properties":{"success":{"type":"boolean","title":"Success"},"candidate_id":{"type":"string","title":"Candidate Id"},"document_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Document Id"}},"type":"object","required":["success","candidate_id"],"title":"ResumeAttachResponse"},"ResumeParseRequest":{"properties":{"resume_text":{"type":"string","title":"Resume Text"},"candidate_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Candidate Id"}},"type":"object","required":["resume_text"],"title":"ResumeParseRequest"},"ResumeParseResponse":{"properties":{"parsed_data":{"additionalProperties":true,"type":"object","title":"Parsed Data"},"candidate_updated":{"type":"boolean","title":"Candidate Updated","default":false}},"type":"object","required":["parsed_data"],"title":"ResumeParseResponse"},"RewardPayoutRequest":{"properties":{"reward_status":{"type":"string","const":"Approved","title":"Reward Status","description":"Must be 'Approved'"},"payout_method":{"type":"string","enum":["stripe_transfer","invoice_credit"],"title":"Payout Method","description":"Payout method"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes","description":"Admin notes"}},"type":"object","required":["reward_status","payout_method"],"title":"RewardPayoutRequest","description":"Request to process reward payout"},"RewardPayoutResponse":{"properties":{"referral_id":{"type":"string","title":"Referral Id"},"reward_amount":{"type":"number","title":"Reward Amount"},"reward_status":{"type":"string","title":"Reward Status"},"reward_payment_id":{"type":"string","title":"Reward Payment Id"},"paid_date":{"type":"string","format":"date-time","title":"Paid Date"},"payout_method":{"type":"string","title":"Payout Method"},"message":{"type":"string","title":"Message"}},"type":"object","required":["referral_id","reward_amount","reward_status","reward_payment_id","paid_date","payout_method","message"],"title":"RewardPayoutResponse","description":"Response after processing reward"},"RoleIn":{"properties":{"title":{"type":"string","maxLength":200,"minLength":2,"title":"Title"},"seniority":{"anyOf":[{"type":"string","enum":["junior","mid","senior","staff"]},{"type":"null"}],"title":"Seniority"},"stack":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Stack"},"notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Notes"},"prefill_source":{"anyOf":[{"type":"string","const":"company_memory"},{"type":"null"}],"title":"Prefill Source"}},"type":"object","required":["title"],"title":"RoleIn"},"RolePatch":{"properties":{"user_id":{"type":"string","title":"User Id"},"title":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Title"},"status":{"anyOf":[{"type":"string","enum":["open","paused","filled","closed"]},{"type":"null"}],"title":"Status"},"seniority":{"anyOf":[{"type":"string","enum":["junior","mid","senior","staff"]},{"type":"null"}],"title":"Seniority"},"stack":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":20},{"type":"null"}],"title":"Stack"},"notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Notes"}},"type":"object","required":["user_id"],"title":"RolePatch"},"RunIn":{"properties":{"dry_run":{"type":"boolean","title":"Dry Run","default":false},"company_domain":{"anyOf":[{"type":"string","maxLength":253},{"type":"null"}],"title":"Company Domain"}},"type":"object","title":"RunIn"},"RunPipelineRequest":{"properties":{"user_prompt":{"type":"string","title":"User Prompt","description":"Instruction for the agentic pipeline. Start with [AGENT] for agentic mode."},"skill":{"type":"string","title":"Skill","description":"Which skill to load as the system prompt (must exist in app/skills/).","default":"enrich-leads"}},"type":"object","required":["user_prompt"],"title":"RunPipelineRequest"},"SalesActivityCreate":{"properties":{"activity_type":{"type":"string","pattern":"^(call|email|meeting|note)$","title":"Activity Type","description":"Activity type"},"lead_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lead Id"},"company_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Id"},"placement_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Placement Id"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"metadata_json":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metadata Json"}},"type":"object","required":["activity_type"],"title":"SalesActivityCreate"},"SaveDraftRequest":{"properties":{"code":{"anyOf":[{"type":"string","maxLength":200000},{"type":"null"}],"title":"Code"},"answers":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Answers"},"elapsed_seconds":{"type":"integer","maximum":86400.0,"minimum":0.0,"title":"Elapsed Seconds","default":0},"client_saved_at":{"type":"string","format":"date-time","title":"Client Saved At"},"telemetry":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"number"}]},"type":"object"},{"type":"null"}],"title":"Telemetry"},"pasted":{"type":"boolean","title":"Pasted","default":false},"pasted_snippets":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Pasted Snippets"}},"type":"object","required":["client_saved_at"],"title":"SaveDraftRequest","description":"A heartbeat from the assessment page. Fires every ~15s and on blur."},"SaveIn":{"properties":{"ref":{"type":"string","maxLength":20,"title":"Ref"},"snapshot":{"additionalProperties":true,"type":"object","title":"Snapshot"}},"type":"object","required":["ref"],"title":"SaveIn"},"ScheduleInterviewRequest":{"properties":{"interview_date":{"type":"string","format":"date-time","title":"Interview Date"},"interview_type":{"type":"string","title":"Interview Type"},"interview_duration":{"anyOf":[{"type":"integer","maximum":480.0,"minimum":15.0},{"type":"null"}],"title":"Interview Duration","default":60},"interview_link":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Interview Link"},"interviewer_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Interviewer Name"}},"type":"object","required":["interview_date","interview_type"],"title":"ScheduleInterviewRequest"},"SearchIn":{"properties":{"query":{"type":"string","maxLength":300,"minLength":2,"title":"Query"}},"type":"object","required":["query"],"title":"SearchIn"},"SearchRequest":{"properties":{"keywords":{"type":"string","title":"Keywords"},"location":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Location"},"max_results":{"type":"integer","title":"Max Results","default":25},"enrich":{"type":"boolean","title":"Enrich","default":false},"offset":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Offset"}},"type":"object","required":["keywords"],"title":"SearchRequest","description":"Request model for LinkedIn search"},"SendIn":{"properties":{"task_slug":{"anyOf":[{"type":"string","maxLength":60},{"type":"null"}],"title":"Task Slug"},"expires_in_days":{"type":"integer","maximum":30.0,"minimum":1.0,"title":"Expires In Days","default":7}},"type":"object","title":"SendIn"},"SendInterviewRequest":{"properties":{"template_id":{"type":"string","format":"uuid","title":"Template Id"},"expires_in_days":{"type":"integer","maximum":30.0,"minimum":1.0,"title":"Expires In Days","default":14}},"type":"object","required":["template_id"],"title":"SendInterviewRequest","description":"POST /api/candidates/{id}/send-interview"},"SendLiveScreenInviteResponse":{"properties":{"meeting_id":{"type":"string","format":"uuid","title":"Meeting Id"},"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"invited_at":{"type":"string","format":"date-time","title":"Invited At"},"cal_url":{"type":"string","title":"Cal Url"},"email_sent":{"type":"boolean","title":"Email Sent"}},"type":"object","required":["meeting_id","candidate_id","invited_at","cal_url","email_sent"],"title":"SendLiveScreenInviteResponse","description":"Response from POST /api/candidates/{id}/send-live-screen-invite."},"SendMessageRequest":{"properties":{"content":{"type":"string","title":"Content"},"account_id":{"type":"string","title":"Account Id","default":"acc1"}},"type":"object","required":["content"],"title":"SendMessageRequest"},"SendShortlistRequest":{"properties":{"candidate_ids":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":10,"minItems":1,"title":"Candidate Ids"},"to_email":{"type":"string","format":"email","title":"To Email"},"cc_emails":{"anyOf":[{"items":{"type":"string","format":"email"},"type":"array","maxItems":5},{"type":"null"}],"title":"Cc Emails"},"blind":{"type":"boolean","title":"Blind","description":"Anonymize names + companies in attached PDFs.","default":true},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note","description":"Personal note prepended to the email body."}},"type":"object","required":["candidate_ids","to_email"],"title":"SendShortlistRequest","description":"POST /api/projects/{id}/send-shortlist."},"SendShortlistResponse":{"properties":{"project_id":{"type":"string","format":"uuid","title":"Project Id"},"sent_to":{"type":"string","title":"Sent To"},"candidate_count":{"type":"integer","title":"Candidate Count"},"document_ids":{"items":{"type":"string","format":"uuid"},"type":"array","title":"Document Ids"},"track_ids":{"items":{"type":"string"},"type":"array","title":"Track Ids"},"sent_at":{"type":"string","format":"date-time","title":"Sent At"}},"type":"object","required":["project_id","sent_to","candidate_count","document_ids","track_ids","sent_at"],"title":"SendShortlistResponse"},"SessionProofIn":{"properties":{"session_id":{"type":"string","maxLength":64,"minLength":8,"title":"Session Id"},"proof":{"type":"string","maxLength":2048,"minLength":10,"title":"Proof"}},"type":"object","required":["session_id","proof"],"title":"SessionProofIn"},"ShortlistIn":{"properties":{"refs":{"items":{"type":"string"},"type":"array","maxItems":20,"minItems":1,"title":"Refs"},"role":{"type":"string","maxLength":200,"minLength":2,"title":"Role"},"seniority":{"type":"string","pattern":"^(mid|senior|staff)$","title":"Seniority","default":"senior"},"full_name":{"anyOf":[{"type":"string","maxLength":160},{"type":"null"}],"title":"Full Name"},"company":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Company"},"notes":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Notes"},"role_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Id"}},"type":"object","required":["refs","role"],"title":"ShortlistIn"},"ShortlistProofIn":{"properties":{"token":{"type":"string","maxLength":128,"minLength":16,"title":"Token"}},"type":"object","required":["token"],"title":"ShortlistProofIn"},"ShortlistRequestCreate":{"properties":{"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"utm_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Content"},"utm_term":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Term"},"referrer_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Url"},"landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Landing Page"},"first_touch_landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Touch Landing Page"},"full_name":{"type":"string","title":"Full Name"},"work_email":{"type":"string","format":"email","title":"Work Email"},"company":{"type":"string","title":"Company"},"role":{"type":"string","title":"Role"},"seniority":{"type":"string","title":"Seniority"},"skills":{"type":"string","title":"Skills","default":""},"engineers":{"type":"integer","title":"Engineers","default":1},"timeline":{"type":"string","title":"Timeline","default":""},"notes":{"type":"string","title":"Notes","default":""},"referrer_origin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Origin"},"session_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Session Id"},"required_skills":{"items":{"type":"string"},"type":"array","title":"Required Skills","default":[]},"preferred_skills":{"items":{"type":"string"},"type":"array","title":"Preferred Skills","default":[]},"role_slug":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role Slug"}},"type":"object","required":["full_name","work_email","company","role","seniority"],"title":"ShortlistRequestCreate","description":"Shortlist request from /request-shortlist (P0 staff aug intake)."},"SolDegradedCreate":{"properties":{"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"utm_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Content"},"utm_term":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Term"},"referrer_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Url"},"landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Landing Page"},"first_touch_landing_page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Touch Landing Page"},"email":{"type":"string","format":"email","title":"Email"},"session_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Session Id"},"surface":{"type":"string","enum":["intake","shortlist","lp","app"],"title":"Surface","default":"intake"},"page_url":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"title":"Page Url"},"transcript":{"items":{"$ref":"#/components/schemas/SolDegradedTranscriptMessage"},"type":"array","maxItems":200,"title":"Transcript"},"error_kind":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Error Kind"}},"type":"object","required":["email"],"title":"SolDegradedCreate","description":"utm_*, referrer_url, landing_page, first_touch_landing_page come from\nWebAttributionMixin (www passes its attribution; the Sol App sends none)."},"SolDegradedTranscriptMessage":{"properties":{"role":{"type":"string","enum":["user","assistant"],"title":"Role"},"content":{"type":"string","maxLength":20000,"minLength":1,"title":"Content"},"timestamp":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Timestamp"}},"type":"object","required":["role","content"],"title":"SolDegradedTranscriptMessage"},"SourceCostRequest":{"properties":{"month":{"type":"string","title":"Month"},"signal_source":{"type":"string","title":"Signal Source"},"unit_cost_cents":{"type":"integer","title":"Unit Cost Cents"},"quantity":{"type":"integer","title":"Quantity"},"total_cost_cents":{"type":"integer","title":"Total Cost Cents"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["month","signal_source","unit_cost_cents","quantity","total_cost_cents"],"title":"SourceCostRequest","description":"Track B Workflow #6 — monthly per-source cost entry."},"SpeedReceiptOut":{"properties":{"eligible":{"type":"boolean","title":"Eligible"},"median_hours":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Median Hours"},"sample_size":{"type":"integer","title":"Sample Size"},"window_days":{"type":"integer","title":"Window Days"},"promise_hours":{"type":"integer","title":"Promise Hours"}},"type":"object","required":["eligible","sample_size","window_days","promise_hours"],"title":"SpeedReceiptOut","description":"The Epic 5.7 receipt: \"median time to shortlist over the last 30 days\".\n\n``eligible`` is the whole contract. It is false whenever the sample is\ntoo small OR the measured median does not beat the published promise,\nand in that case ``median_hours`` is ``None`` — withheld, not merely\nunflagged, so a renderer cannot reach past the flag and print a number\nit was not cleared to print. The consumer falls back to the plain\n72-hour guarantee copy, which is true either way.\n\nAn absent stat row (never computed) is reported identically to an\nineligible one, because the page behaves identically."},"StartAssessmentBody":{"properties":{"package_slug":{"type":"string","maxLength":80,"minLength":1,"title":"Package Slug"}},"type":"object","required":["package_slug"],"title":"StartAssessmentBody"},"StartBody":{"properties":{"referrer_origin":{"anyOf":[{"type":"string","maxLength":50},{"type":"null"}],"title":"Referrer Origin"}},"type":"object","title":"StartBody"},"SubmitAssessmentRequest":{"properties":{"code":{"type":"string","maxLength":200000,"title":"Code","default":""},"question_answers":{"additionalProperties":{"anyOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]},"type":"object","title":"Question Answers"},"telemetry":{"anyOf":[{"additionalProperties":{"anyOf":[{"type":"integer"},{"type":"number"}]},"type":"object"},{"type":"null"}],"title":"Telemetry"},"pasted_code":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pasted Code"},"pasted_snippets":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Pasted Snippets"}},"type":"object","title":"SubmitAssessmentRequest","description":"POST /api/coding-assessment/{token}/submit payload.\n\n`code` carries the editor contents. It is REQUIRED for a coding\nassessment and ignored for a questions-only one — which of the two this\ntoken is cannot be known from the payload, so the service enforces it\n(409 \"A coding assessment needs a code submission.\") rather than the\nschema.\n\n`question_answers` maps question_slug to either:\n  - str (text answer for short_text / long_text questions)\n  - list[str] (selected choice values for single_choice / multi_choice)\n\nRequired only if the assessment has a package; ignored otherwise.\nEmpty answers persist with score 0."},"SubmitAssessmentResponse":{"properties":{"status":{"type":"string","enum":["sent","in_progress","submitted","graded","expired","errored"],"title":"Status"},"visible_passed":{"type":"integer","title":"Visible Passed"},"visible_total":{"type":"integer","title":"Visible Total"},"submitted_at":{"type":"string","format":"date-time","title":"Submitted At"}},"type":"object","required":["status","visible_passed","visible_total","submitted_at"],"title":"SubmitAssessmentResponse","description":"Sanitized — candidate-facing only. No score, no hidden-test info,\nno AI rubric. Recruiter sees the full picture via RecruiterAssessmentView."},"SubmitCandidateRequest":{"properties":{"candidate_id":{"type":"string","title":"Candidate Id","description":"Candidate to submit"},"proposed_rate":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Proposed Rate"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"}},"type":"object","required":["candidate_id"],"title":"SubmitCandidateRequest"},"SubmitIn":{"properties":{"diff":{"type":"string","maxLength":61000,"title":"Diff"},"agent_log":{"type":"string","maxLength":31000,"title":"Agent Log"},"reflections":{"additionalProperties":{"type":"string"},"type":"object","title":"Reflections"},"assistant":{"type":"string","maxLength":60,"title":"Assistant"}},"type":"object","required":["diff","agent_log","reflections","assistant"],"title":"SubmitIn"},"SyncStatusResponse":{"properties":{"last_sync":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Sync"},"cached_conversations":{"type":"integer","title":"Cached Conversations"},"unread_count":{"type":"integer","title":"Unread Count"},"has_client":{"type":"boolean","title":"Has Client"}},"type":"object","required":["last_sync","cached_conversations","unread_count","has_client"],"title":"SyncStatusResponse"},"TaskCreate":{"properties":{"title":{"type":"string","title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"domain":{"type":"string","title":"Domain","default":"marketing"},"task_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Type"},"platform":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Platform"},"scheduled_date":{"type":"string","title":"Scheduled Date"},"scheduled_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scheduled Time"},"priority":{"type":"string","title":"Priority","default":"medium"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"task_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Task Metadata"},"recurrence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence"},"recurrence_anchor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence Anchor"},"recurrence_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence End"},"assignee_kind":{"type":"string","title":"Assignee Kind","default":"unassigned"},"assignee_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assignee Ref"}},"type":"object","required":["title","scheduled_date"],"title":"TaskCreate"},"TaskUpdate":{"properties":{"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"description":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Description"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Content"},"notes":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Notes"},"completed_by":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed By"},"scheduled_date":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scheduled Date"},"scheduled_time":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scheduled Time"},"priority":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Priority"},"task_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Task Type"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"recurrence":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence"},"recurrence_anchor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence Anchor"},"recurrence_end":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Recurrence End"},"assignee_kind":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assignee Kind"},"assignee_ref":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Assignee Ref"},"handler_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Handler Status"}},"type":"object","title":"TaskUpdate"},"TestCase":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"stdin":{"type":"string","title":"Stdin","default":""},"expected_stdout":{"type":"string","title":"Expected Stdout"}},"type":"object","required":["expected_stdout"],"title":"TestCase","description":"Single Piston-style stdin/stdout pair."},"TestMarkerBody":{"properties":{"is_test":{"type":"boolean","title":"Is Test"},"reason":{"anyOf":[{"type":"string","maxLength":4000},{"type":"null"}],"title":"Reason"}},"type":"object","required":["is_test"],"title":"TestMarkerBody"},"TheirStackSearchRequest":{"properties":{"job_titles":{"items":{"type":"string"},"type":"array","maxItems":20,"minItems":1,"title":"Job Titles"},"countries":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Countries"},"company_sizes":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Company Sizes"},"min_employees":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Min Employees"},"max_employees":{"anyOf":[{"type":"integer","maximum":100000.0,"minimum":1.0},{"type":"null"}],"title":"Max Employees"},"job_countries":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Job Countries"},"posted_within_days":{"type":"integer","maximum":90.0,"minimum":1.0,"title":"Posted Within Days","default":21},"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","default":30},"exclude_competitors":{"type":"boolean","title":"Exclude Competitors","default":true}},"type":"object","required":["job_titles"],"title":"TheirStackSearchRequest","description":"Search filters for TheirStack company discovery.\n\nCredit-burn guards (per /scr Warning #1 + project_vp_credit_burn_lesson\nmemory — $40 mistake on omitted page_size). Bounds match the realistic\nPhase 0-3 weekly injection ceiling (~70 leads/wk × ~3 credits/co\n≈ 210 credits/run cap). Anyone asking for more than 100 companies in\none call is either making a mistake or doing something the skill\nshouldn't do unsupervised."},"TokenIn":{"properties":{"token":{"type":"string","maxLength":200,"title":"Token"}},"type":"object","required":["token"],"title":"TokenIn"},"TransferRequest":{"properties":{"engineer_id":{"type":"string","title":"Engineer Id"},"amount":{"type":"number","title":"Amount"},"currency":{"type":"string","enum":["ARS","BRL","COP","MXN","USD"],"title":"Currency"}},"type":"object","required":["engineer_id","amount","currency"],"title":"TransferRequest","description":"Single transfer request"},"TransferResponse":{"properties":{"engineer_id":{"type":"string","title":"Engineer Id"},"engineer_name":{"type":"string","title":"Engineer Name"},"status":{"type":"string","enum":["success","failed"],"title":"Status"},"transfer_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Transfer Id"},"amount_usd":{"type":"number","title":"Amount Usd"},"fee":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fee"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"payment_record_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Payment Record Id"}},"type":"object","required":["engineer_id","engineer_name","status","amount_usd"],"title":"TransferResponse","description":"Transfer response"},"TurnBody":{"properties":{"read_id":{"type":"string","format":"uuid","title":"Read Id"},"message":{"type":"string","maxLength":4000,"minLength":1,"title":"Message"}},"type":"object","required":["read_id","message"],"title":"TurnBody"},"TurnIn":{"properties":{"user_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Id"},"anon_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Anon Id"},"messages":{"items":{"$ref":"#/components/schemas/TurnMessage"},"type":"array","maxItems":4,"minItems":1,"title":"Messages"},"attribution":{"anyOf":[{"additionalProperties":{"type":"string"},"type":"object"},{"type":"null"}],"title":"Attribution"}},"type":"object","required":["messages"],"title":"TurnIn"},"TurnMessage":{"properties":{"role":{"type":"string","pattern":"^(user|assistant)$","title":"Role"},"content":{"type":"string","maxLength":60000,"title":"Content","default":""},"cards":{"items":{},"type":"array","maxItems":8,"title":"Cards"},"artifacts":{"items":{},"type":"array","maxItems":4,"title":"Artifacts"},"tools_used":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Tools Used"},"model":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Model"},"input_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Input Tokens"},"output_tokens":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Output Tokens"}},"type":"object","required":["role"],"title":"TurnMessage"},"TypedAnswerIn":{"properties":{"answer_text":{"type":"string","maxLength":20000,"title":"Answer Text"}},"type":"object","required":["answer_text"],"title":"TypedAnswerIn","description":"One typed answer. The free vetting tier's input shape.\n\n`max_length` is generous on purpose — the service enforces the real\n6,000-character limit with a message the candidate can act on. This\nbound exists one layer earlier so an oversized body is rejected during\nvalidation instead of being parsed into memory first."},"UpdateCampaignRequest":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"target_persona":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Target Persona"},"connection_template":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connection Template"},"message_template":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Template"},"followup_template":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Followup Template"},"message_delay_hours":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Message Delay Hours"},"followup_delay_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Followup Delay Days"},"max_followups":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Followups"},"auto_approve_threshold":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Approve Threshold"},"linkedin_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Account Id"}},"type":"object","title":"UpdateCampaignRequest"},"UpdateMessageRequest":{"properties":{"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"connect_note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connect Note"},"message_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Message Body"},"followup_body":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Followup Body"}},"type":"object","title":"UpdateMessageRequest"},"UpdateStatusRequest":{"properties":{"status":{"type":"string","title":"Status"}},"type":"object","required":["status"],"title":"UpdateStatusRequest"},"UpdateToggleRequest":{"properties":{"enabled":{"type":"boolean","title":"Enabled"}},"type":"object","required":["enabled"],"title":"UpdateToggleRequest"},"UsageLogRequest":{"properties":{"service":{"type":"string","title":"Service"},"operation":{"type":"string","title":"Operation"},"model":{"type":"string","title":"Model"},"input_tokens":{"type":"integer","title":"Input Tokens"},"output_tokens":{"type":"integer","title":"Output Tokens"},"cache_creation_input_tokens":{"type":"integer","title":"Cache Creation Input Tokens","default":0},"cache_read_input_tokens":{"type":"integer","title":"Cache Read Input Tokens","default":0},"session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Session Id"},"metadata_json":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Metadata Json"}},"type":"object","required":["service","operation","model","input_tokens","output_tokens"],"title":"UsageLogRequest","description":"Request body for external services to log AI usage."},"UsageSummaryResponse":{"properties":{"service":{"type":"string","title":"Service"},"operation":{"type":"string","title":"Operation"},"model":{"type":"string","title":"Model"},"call_count":{"type":"integer","title":"Call Count"},"total_input_tokens":{"type":"integer","title":"Total Input Tokens"},"total_output_tokens":{"type":"integer","title":"Total Output Tokens"},"total_cost_usd":{"type":"number","title":"Total Cost Usd"}},"type":"object","required":["service","operation","model","call_count","total_input_tokens","total_output_tokens","total_cost_usd"],"title":"UsageSummaryResponse"},"UserResponse":{"properties":{"id":{"type":"string","title":"Id"},"email":{"type":"string","title":"Email"},"first_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"First Name"},"last_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Name"},"role":{"type":"string","enum":["founder","client_admin","client_user","recruiter","sales_rep"],"title":"Role"},"company_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Id"},"is_active":{"type":"boolean","title":"Is Active","default":true}},"type":"object","required":["id","email","role"],"title":"UserResponse","description":"User data response"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VendorRescueContact":{"properties":{"email":{"type":"string","maxLength":320,"minLength":3,"title":"Email"},"first_name":{"type":"string","maxLength":100,"minLength":1,"title":"First Name"},"last_name":{"type":"string","maxLength":100,"title":"Last Name","default":""},"title":{"type":"string","maxLength":255,"title":"Title","default":""}},"type":"object","required":["email","first_name"],"title":"VendorRescueContact"},"VendorRescueDismissRequest":{"properties":{"ids":{"items":{"type":"string","format":"uuid"},"type":"array","maxItems":200,"minItems":1,"title":"Ids"}},"type":"object","required":["ids"],"title":"VendorRescueDismissRequest"},"VendorRescueFinding":{"properties":{"target_domain":{"type":"string","maxLength":255,"minLength":3,"title":"Target Domain"},"target_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Target Name"},"country":{"type":"string","maxLength":2,"minLength":2,"title":"Country"},"vendor_name":{"type":"string","maxLength":100,"minLength":1,"title":"Vendor Name"},"trigger":{"type":"string","maxLength":50,"minLength":1,"title":"Trigger"},"tier":{"type":"integer","maximum":4.0,"minimum":1.0,"title":"Tier","default":2},"event_date":{"anyOf":[{"type":"string","maxLength":10},{"type":"null"}],"title":"Event Date"},"source_url":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Source Url"},"note":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Note"},"contact":{"anyOf":[{"$ref":"#/components/schemas/VendorRescueContact"},{"type":"null"}]}},"type":"object","required":["target_domain","country","vendor_name","trigger"],"title":"VendorRescueFinding"},"VendorRescueFindingsRequest":{"properties":{"findings":{"items":{"$ref":"#/components/schemas/VendorRescueFinding"},"type":"array","maxItems":50,"minItems":1,"title":"Findings"},"dry_run":{"type":"boolean","title":"Dry Run","default":false}},"type":"object","required":["findings"],"title":"VendorRescueFindingsRequest"},"VerifyCodeBody":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"code":{"type":"string","maxLength":8,"minLength":4,"title":"Code"},"name":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Name"},"target_role":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Target Role"}},"type":"object","required":["email","code"],"title":"VerifyCodeBody","description":"The code, plus whatever the signup form collected alongside it.\n\n`name` and `target_role` ride on VERIFY rather than on `request-code`\nfor one reason: request-code must answer identically for a known and an\nunknown address, and a body that only a newcomer fills in is a shape an\nattacker can probe. By verify time the OTP has already proved the inbox,\nso there is nothing left to leak.\n\nBoth are optional. The sign-in and magic-link modes of the page do not\nask for them, the welcome-email claim path does not either, and a signup\nmust never fail because a courtesy field was blank."},"VerifyIn":{"properties":{"email":{"type":"string","maxLength":254,"title":"Email"},"code":{"type":"string","maxLength":12,"title":"Code"},"anon_id":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Anon Id"},"user_agent":{"anyOf":[{"type":"string","maxLength":400},{"type":"null"}],"title":"User Agent"},"partner_slug":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Partner Slug"}},"type":"object","required":["email","code"],"title":"VerifyIn"},"VetoPayload":{"properties":{"excluded":{"type":"boolean","title":"Excluded"}},"type":"object","required":["excluded"],"title":"VetoPayload"},"VettingCandidateIn":{"properties":{"name":{"type":"string","maxLength":160,"minLength":2,"title":"Name"},"github_url":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Github Url"},"linkedin_url":{"anyOf":[{"type":"string","maxLength":300},{"type":"null"}],"title":"Linkedin Url"},"email":{"anyOf":[{},{"type":"null"}],"title":"Email"}},"type":"object","required":["name"],"title":"VettingCandidateIn","description":"A person the requester already found.\n\n``email`` is OPTIONAL and means \"send it for me\". The ask still comes\nfrom the company; Ruzora only delivers it. It is read only for a\nVERIFIED requester with VETTING_SEND_INVITE_ENABLED on (see\n``_may_send_invites``); for anyone else it is ignored and never stored.\nA plain string, not EmailStr: the service validates it and words the\nrefusal without echoing the value. See vetting_service's module\ndocstring, decision 1.\n\nUntyped ON PURPOSE (PR #528 e2e N1): with the flag off, or for an\nunverified caller, any ``email`` value is ignored exactly as the extra\nkey it used to be, never a new 422. ``normalize_invite_email`` validates\nit (type and length included) only when it will be used."},"VettingRequestIn":{"properties":{"requester_name":{"type":"string","maxLength":160,"minLength":2,"title":"Requester Name"},"work_email":{"type":"string","format":"email","title":"Work Email"},"company":{"type":"string","maxLength":200,"minLength":1,"title":"Company"},"role":{"type":"string","maxLength":200,"minLength":2,"title":"Role"},"stack":{"type":"string","title":"Stack","default":""},"tier":{"type":"string","title":"Tier","default":"free"},"candidates":{"items":{"$ref":"#/components/schemas/VettingCandidateIn"},"type":"array","maxItems":5,"minItems":1,"title":"Candidates"},"confirmed":{"type":"boolean","title":"Confirmed","default":false},"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"}},"type":"object","required":["requester_name","work_email","company","role","candidates"],"title":"VettingRequestIn"},"VibeProspectingImportRequest":{"properties":{"leads":{"items":{"$ref":"#/components/schemas/VibeProspectingLead"},"type":"array","minItems":1,"title":"Leads"},"source":{"type":"string","title":"Source","default":"VibeProspecting"},"auto_assign":{"type":"boolean","title":"Auto Assign","default":true},"signal_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signal Source"},"activation_channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Activation Channel"},"signal_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Signal Metadata"}},"type":"object","required":["leads"],"title":"VibeProspectingImportRequest"},"VibeProspectingImportResult":{"properties":{"total":{"type":"integer","title":"Total"},"created":{"type":"integer","title":"Created"},"skipped_duplicates":{"type":"integer","title":"Skipped Duplicates"},"updated_enrichment":{"type":"integer","title":"Updated Enrichment"},"skipped_existing_clients":{"type":"integer","title":"Skipped Existing Clients"},"errors":{"type":"integer","title":"Errors"},"created_ids":{"items":{"type":"string"},"type":"array","title":"Created Ids"},"updated_ids":{"items":{"type":"string"},"type":"array","title":"Updated Ids"},"skipped_emails":{"items":{"type":"string"},"type":"array","title":"Skipped Emails"},"existing_client_domains":{"items":{"type":"string"},"type":"array","title":"Existing Client Domains"},"auto_send_enabled":{"type":"boolean","title":"Auto Send Enabled","default":true},"pending_activation_ids":{"items":{"type":"string"},"type":"array","title":"Pending Activation Ids","default":[]}},"type":"object","required":["total","created","skipped_duplicates","updated_enrichment","skipped_existing_clients","errors","created_ids","updated_ids","skipped_emails","existing_client_domains"],"title":"VibeProspectingImportResult"},"VibeProspectingLead":{"properties":{"first_name":{"type":"string","title":"First Name"},"last_name":{"type":"string","title":"Last Name"},"email":{"type":"string","title":"Email"},"company":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company","default":""},"role":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Role","default":""},"hiring_need":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Hiring Need","default":""},"seats_needed":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Seats Needed","default":1},"timeline":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Timeline","default":""},"phone":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Phone"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"},"explorium_business_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explorium Business Id"},"explorium_prospect_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Explorium Prospect Id"},"company_domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Domain"},"company_size_range":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Size Range"},"company_revenue_range":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Company Revenue Range"},"tech_stack":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tech Stack"},"intent_score":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Intent Score"},"intent_topics":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Intent Topics"},"funding_stage":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Funding Stage"},"funding_amount":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Funding Amount"},"workforce_trend":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Workforce Trend"},"signal_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Signal Source"},"activation_channel":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Activation Channel"},"signal_metadata":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Signal Metadata"},"email_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email Source"},"email_verification_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email Verification Status"}},"type":"object","required":["first_name","last_name","email"],"title":"VibeProspectingLead"},"WebVerifyConfirmIn":{"properties":{"work_email":{"type":"string","maxLength":254,"title":"Work Email"},"code":{"type":"string","maxLength":12,"minLength":4,"title":"Code"},"verification_id":{"type":"string","maxLength":64,"minLength":8,"title":"Verification Id"}},"type":"object","required":["work_email","code","verification_id"],"title":"WebVerifyConfirmIn"},"WebVerifyRequestIn":{"properties":{"work_email":{"type":"string","maxLength":254,"title":"Work Email"}},"type":"object","required":["work_email"],"title":"WebVerifyRequestIn"},"_ChatQuestionBody":{"properties":{"question":{"type":"string","maxLength":2000,"minLength":1,"title":"Question"}},"type":"object","required":["question"],"title":"_ChatQuestionBody","description":"A question Sol couldn't answer from the blind context — routed to\nthe team with a 4h response promise."},"_FeedbackBody":{"properties":{"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"sentiment":{"type":"string","pattern":"^(up|down)$","title":"Sentiment"},"reasons":{"items":{"type":"string"},"type":"array","maxItems":8,"title":"Reasons"},"note":{"anyOf":[{"type":"string","maxLength":500},{"type":"null"}],"title":"Note"}},"type":"object","required":["candidate_id","sentiment"],"title":"_FeedbackBody","description":"One tap on one card (Epic 5.4).\n\n`reasons` are chip SLUGS from shortlist_feedback_service.REASON_CHIPS\nand are only meaningful on a thumbs-down; the service drops them for\n'up' rather than 422-ing, because a client that sends them is\nharmlessly out of date, not malicious."},"_MarkPaidBody":{"properties":{"note":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Note"}},"type":"object","title":"_MarkPaidBody"},"_PublishBody":{"properties":{"items":{"items":{"$ref":"#/components/schemas/_PublishItem"},"type":"array","maxItems":20,"minItems":1,"title":"Items"},"notify_lead":{"type":"boolean","title":"Notify Lead","default":true}},"type":"object","required":["items"],"title":"_PublishBody"},"_PublishItem":{"properties":{"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"position":{"type":"integer","maximum":20.0,"minimum":1.0,"title":"Position"},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note"}},"type":"object","required":["candidate_id","position"],"title":"_PublishItem"},"_RequestIntroBody":{"properties":{"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note"}},"type":"object","required":["candidate_id"],"title":"_RequestIntroBody"},"_RequestIntroByPositionBody":{"properties":{"position":{"type":"integer","maximum":20.0,"minimum":1.0,"title":"Position"},"note":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Note"}},"type":"object","required":["position"],"title":"_RequestIntroByPositionBody","description":"Sol concierge variant — chat-api addresses candidates by card\nposition and never holds candidate_ids (Sol v2 §16)."},"_ShareBody":{"properties":{"recipients":{"anyOf":[{"items":{"$ref":"#/components/schemas/_ShareRecipient"},"type":"array"},{"type":"null"}],"title":"Recipients"},"email":{"anyOf":[{"type":"string","maxLength":320},{"type":"null"}],"title":"Email"},"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"}},"type":"object","title":"_ShareBody","description":"Share this shortlist with colleagues (Epic 5.3).\n\nB2B staffing decisions are committee decisions, so `recipients` is the\nreal shape. `email`/`name` are kept because the first release shipped\nthem and an older tab may still be open; they fold into a\nsingle-element list.\n\nEmailStr is deliberately NOT used: pydantic's email validator pulls in\n`email-validator` and rejects addresses that real corporate mail\nservers accept. A shape check plus the send attempt is the honest\ngate — a typo'd address bounces, which is visible in email_events."},"_ShareRecipient":{"properties":{"email":{"type":"string","maxLength":320,"minLength":5,"title":"Email"},"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"}},"type":"object","required":["email"],"title":"_ShareRecipient","description":"One colleague. `name` is optional and only greets them in the mail."},"_TrackViewBody":{"properties":{"candidate_id":{"type":"string","format":"uuid","title":"Candidate Id"}},"type":"object","required":["candidate_id"],"title":"_TrackViewBody"},"app__models__assessment__SendAssessmentRequest":{"properties":{"code_challenge_link":{"type":"string","maxLength":500,"minLength":8,"title":"Code Challenge Link"},"assessment_id":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Assessment Id","description":"Provider's internal id; optional — derived from link if omitted."}},"type":"object","required":["code_challenge_link"],"title":"SendAssessmentRequest","description":"POST /api/candidates/{id}/send-assessment\n\nRoberto pastes the code-challenge link from his recruiter dashboard.\nWe accept either the full https link or just the assessment_id —\nwhichever the provider gives. The field stays generic so we can swap\nproviders without churning the API shape."},"app__models__coding_challenge__SendAssessmentRequest":{"properties":{"package_slug":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Package Slug"},"challenge_slug":{"anyOf":[{"type":"string","maxLength":80},{"type":"null"}],"title":"Challenge Slug"},"project_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Project Id","description":"Optional context — if set, server resolves project's default_package_slug when both slug fields are empty."},"expires_in_days":{"type":"integer","maximum":30.0,"minimum":1.0,"title":"Expires In Days","default":10}},"type":"object","title":"SendAssessmentRequest","description":"POST /api/candidates/{id}/send-coding-assessment payload.\n\nProvide exactly one of:\n  package_slug   (recommended — bundles a coding challenge + N questions)\n  challenge_slug (legacy single-challenge mode, kept for back-compat)\n\nIf neither is provided, the API tries to resolve the candidate's project\npipeline → projects.default_package_slug. Talent-pool candidates with no\nproject association will get a 400 with guidance."},"app__routers__marketing_tasks__BulkImport":{"properties":{"tasks":{"items":{"$ref":"#/components/schemas/MarketingTaskCreate"},"type":"array","title":"Tasks"}},"type":"object","required":["tasks"],"title":"BulkImport"},"app__routers__tasks__BulkImport":{"properties":{"tasks":{"items":{"$ref":"#/components/schemas/TaskCreate"},"type":"array","title":"Tasks"}},"type":"object","required":["tasks"],"title":"BulkImport"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}