{"openapi":"3.1.0","info":{"title":"Humwork.ai","version":"0.1.0"},"paths":{"/api/v1":{"get":{"tags":["MCP"],"summary":"Mcp Root","operationId":"mcp_root_api_v1_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["MCP"],"summary":"Mcp Rpc","operationId":"mcp_rpc_api_v1_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/manifest":{"get":{"tags":["MCP"],"summary":"Get Mcp Manifest","operationId":"get_mcp_manifest_api_v1_manifest_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/tools/{tool_name}":{"post":{"tags":["MCP"],"summary":"Handle Mcp Tool Call","operationId":"handle_mcp_tool_call_api_v1_tools__tool_name__post","parameters":[{"name":"tool_name","in":"path","required":true,"schema":{"type":"string","title":"Tool Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/tools/{tool_name}/stream":{"post":{"tags":["MCP"],"summary":"Handle Mcp Tool Stream","description":"Removed — all clients use the JSON-RPC endpoint. Returns 410 Gone.","operationId":"handle_mcp_tool_stream_api_v1_tools__tool_name__stream_post","parameters":[{"name":"tool_name","in":"path","required":true,"schema":{"type":"string","title":"Tool Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/experts/profile":{"get":{"tags":["Experts"],"summary":"Get Expert Profile","description":"Get expert profile","operationId":"get_expert_profile_api_v1_experts_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpertProfile"}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["Experts"],"summary":"Update Expert Profile","description":"Update expert profile (name, picture URL, LinkedIn)","operationId":"update_expert_profile_api_v1_experts_profile_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProfileUpdate"}}},"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/v1/experts/profile/skills":{"put":{"tags":["Experts"],"summary":"Update Expert Skills","description":"Update expert skills","operationId":"update_expert_skills_api_v1_experts_profile_skills_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SkillsUpdate"}}},"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/v1/experts/profile-picture":{"post":{"tags":["Experts"],"summary":"Upload Profile Picture","description":"Upload a profile picture to Supabase Storage","operationId":"upload_profile_picture_api_v1_experts_profile_picture_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_upload_profile_picture_api_v1_experts_profile_picture_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/v1/experts/ably-token":{"get":{"tags":["Experts"],"summary":"Get Ably Token","description":"Generate an Ably token for the authenticated expert.\nToken is scoped to only their private channel with subscribe and history capabilities.","operationId":"get_ably_token_api_v1_experts_ably_token_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/app-data":{"get":{"tags":["Experts"],"summary":"Get Expert App Data","description":"Aggregated endpoint that returns ALL expert dashboard data in one request.\n\nReplaces 8 separate endpoints:\n- /experts/profile\n- /experts/stats\n- /experts/questions (available)\n- /experts/active-questions (accepted)\n- /experts/answered-questions\n- /experts/chat-sessions (available)\n- /experts/active-chats\n- /experts/answered-chats\n\nUses Redis caching (10s TTL) to reduce database load.\nExpected response time: 2-10ms (cached) or 80-150ms (uncached)","operationId":"get_expert_app_data_api_v1_experts_app_data_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/questions":{"get":{"tags":["Experts"],"summary":"Get Available Questions","description":"Get questions available for the expert","operationId":"get_available_questions_api_v1_experts_questions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/ExpertQuestionView"},"type":"array","title":"Response Get Available Questions Api V1 Experts Questions Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/questions/{question_id}/accept":{"post":{"tags":["Experts"],"summary":"Accept Question","description":"Accept a question assignment","operationId":"accept_question_api_v1_experts_questions__question_id__accept_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"question_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Question Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/experts/questions/{question_id}/answer":{"post":{"tags":["Experts"],"summary":"Submit Answer","description":"Submit answer for a question (with time-based payment)","operationId":"submit_answer_api_v1_experts_questions__question_id__answer_post","security":[{"HTTPBearer":[]}],"parameters":[{"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/AnswerCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/experts/stats":{"get":{"tags":["Experts"],"summary":"Get Expert Stats","description":"Get expert statistics","operationId":"get_expert_stats_api_v1_experts_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExpertStats"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/questions/{question_id}/details":{"get":{"tags":["Experts"],"summary":"Get Question Details","description":"Get full question details for accepted question (needed for expert UI answer form)","operationId":"get_question_details_api_v1_experts_questions__question_id__details_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"question_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Question Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/experts/active-questions":{"get":{"tags":["Experts"],"summary":"Get Active Questions","description":"Get questions expert has accepted but not yet answered (with proper timing)","operationId":"get_active_questions_api_v1_experts_active_questions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/answered-questions":{"get":{"tags":["Experts"],"summary":"Get Answered Questions","description":"Get questions the expert has answered (for answered questions history page)","operationId":"get_answered_questions_api_v1_experts_answered_questions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/answered-chats":{"get":{"tags":["Experts"],"summary":"Get Answered Chats","description":"Get chat sessions the expert has completed","operationId":"get_answered_chats_api_v1_experts_answered_chats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/chat-sessions":{"get":{"tags":["Experts"],"summary":"Get Available Chat Sessions","description":"Get chat session requests available for the expert","operationId":"get_available_chat_sessions_api_v1_experts_chat_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/active-chats":{"get":{"tags":["Experts"],"summary":"Get Active Chat Sessions","description":"Get chat sessions the expert is currently participating in","operationId":"get_active_chat_sessions_api_v1_experts_active_chats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/chat-sessions/{session_id}/accept":{"post":{"tags":["Experts"],"summary":"Accept Chat Session","description":"Accept a chat session (expert joins the chat)","operationId":"accept_chat_session_api_v1_experts_chat_sessions__session_id__accept_post","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/v1/experts/chat-sessions/{session_id}/messages":{"post":{"tags":["Experts"],"summary":"Send Expert Message","description":"Expert sends a message in a chat session","operationId":"send_expert_message_api_v1_experts_chat_sessions__session_id__messages_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Message Data"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["Experts"],"summary":"Get Chat Session Messages","description":"Get all messages in a chat session (with timing info for expert UI)","operationId":"get_chat_session_messages_api_v1_experts_chat_sessions__session_id__messages_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/v1/experts/stripe/connect":{"post":{"tags":["Experts"],"summary":"Create Stripe Connect Link","description":"Generate Stripe Connect onboarding link for expert.\nAccepts an optional country code (ISO 3166-1 alpha-2) so the Stripe\naccount is created in the expert's actual country — determines which\nbank-account types and identity-verification flows appear.","operationId":"create_stripe_connect_link_api_v1_experts_stripe_connect_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StripeConnectRequest","default":{"country":"US"}}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/stripe/disconnect":{"post":{"tags":["Experts"],"summary":"Disconnect Stripe","description":"Unlink the current Stripe Connect account so the expert can connect a different one.","operationId":"disconnect_stripe_api_v1_experts_stripe_disconnect_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/stripe/status":{"get":{"tags":["Experts"],"summary":"Check Stripe Status","operationId":"check_stripe_status_api_v1_experts_stripe_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/payouts/request":{"post":{"tags":["Experts"],"summary":"Request Payout","description":"Expert requests payout - creates PENDING request for admin approval","operationId":"request_payout_api_v1_experts_payouts_request_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PayoutRequest"}}},"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/v1/experts/payouts/history":{"get":{"tags":["Experts"],"summary":"Get Payout History","description":"Get expert's payout history (all requests - pending, approved, rejected)","operationId":"get_payout_history_api_v1_experts_payouts_history_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/status":{"put":{"tags":["Experts"],"summary":"Update Expert Status","description":"Update expert availability status\n\nFrontend options map to:\n- \"Available\" → status=\"available\", pause_schedule=false\n- \"Offline\" (scheduled return) → status=\"offline\", pause_schedule=false  \n- \"Offline Indefinitely\" → status=\"offline\", pause_schedule=true\n\nSystem automatically manages BUSY state during active work.","operationId":"update_expert_status_api_v1_experts_status_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusUpdate"}}},"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/v1/experts/init-timezone":{"post":{"tags":["Experts"],"summary":"Init Timezone","description":"Set default 9am-8pm Mon-Sun schedule if the expert has none yet.\n\nCalled by the frontend on first login with the device timezone.\nNo-op if the expert already has a work schedule configured.","operationId":"init_timezone_api_v1_experts_init_timezone_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InitTimezoneRequest"}}},"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/v1/experts/work-schedule":{"get":{"tags":["Experts"],"summary":"Get Work Schedule","description":"Get expert's current work schedule","operationId":"get_work_schedule_api_v1_experts_work_schedule_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"put":{"tags":["Experts"],"summary":"Update Work Schedule","description":"Set or update expert's work hours schedule.\n\nExample payload:\n{\n    \"timezone\": \"America/Los_Angeles\",\n    \"monday\": {\"start\": \"09:00\", \"end\": \"17:00\"},\n    \"tuesday\": {\"start\": \"09:00\", \"end\": \"17:00\"},\n    \"wednesday\": {\"start\": \"09:00\", \"end\": \"17:00\"},\n    \"thursday\": {\"start\": \"09:00\", \"end\": \"17:00\"},\n    \"friday\": {\"start\": \"09:00\", \"end\": \"17:00\"},\n    \"saturday\": null,\n    \"sunday\": null\n}","operationId":"update_work_schedule_api_v1_experts_work_schedule_put","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorkScheduleUpdate"}}},"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":[]}]},"delete":{"tags":["Experts"],"summary":"Delete Work Schedule","description":"Remove work schedule (revert to full manual control)","operationId":"delete_work_schedule_api_v1_experts_work_schedule_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/chat-sessions/{session_id}/close":{"post":{"tags":["Experts"],"summary":"Close Chat Session","description":"Expert closes/completes a chat session (with time-based payment)","operationId":"close_chat_session_api_v1_experts_chat_sessions__session_id__close_post","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/v1/experts/push/subscribe":{"post":{"tags":["Experts"],"summary":"Subscribe To Push","description":"Store expert's push notification subscription.\n\nAccepts two formats:\n- Expo native: {\"expo_push_token\": \"ExponentPushToken[...]\", \"platform\": \"ios\"}\n- Web push:    {\"subscription\": {endpoint, keys, ...}, \"user_agent\": \"...\"}","operationId":"subscribe_to_push_api_v1_experts_push_subscribe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/push/unsubscribe":{"post":{"tags":["Experts"],"summary":"Unsubscribe From Push","description":"Remove expert's push notification subscription.\n\nAccepts either:\n- {\"expo_push_token\": \"ExponentPushToken[...]\"}\n- {\"endpoint\": \"https://...\"}  (web push)","operationId":"unsubscribe_from_push_api_v1_experts_push_unsubscribe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/push/status":{"get":{"tags":["Experts"],"summary":"Get Push Status","description":"Check if expert has any active push subscriptions","operationId":"get_push_status_api_v1_experts_push_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/debug/vapid":{"get":{"tags":["Experts"],"summary":"Debug Vapid","description":"Temporary debug endpoint - DELETE AFTER TESTING","operationId":"debug_vapid_api_v1_experts_debug_vapid_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/experts/debug/cache-stats":{"get":{"tags":["Experts"],"summary":"Get Cache Stats","description":"Check if your dashboard data is currently cached.\nUseful for debugging and monitoring cache performance.","operationId":"get_cache_stats_api_v1_experts_debug_cache_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/qualification/appeal":{"post":{"tags":["Experts"],"summary":"Submit Appeal","description":"Expert submits an appeal to retake the qualification interview.","operationId":"submit_appeal_api_v1_experts_qualification_appeal_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/qualification/eligibility":{"get":{"tags":["Experts"],"summary":"Get Qualification Eligibility","description":"Check if the expert can take/retake the qualification interview.","operationId":"get_qualification_eligibility_api_v1_experts_qualification_eligibility_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/admin/appeals":{"get":{"tags":["Experts"],"summary":"Get Appeals","description":"Admin: list all pending appeals.","operationId":"get_appeals_api_v1_experts_admin_appeals_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/experts/admin/appeals/{expert_id}/approve":{"post":{"tags":["Experts"],"summary":"Approve Appeal","description":"Admin: approve an appeal, allowing the expert to retake.","operationId":"approve_appeal_api_v1_experts_admin_appeals__expert_id__approve_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"expert_id","in":"path","required":true,"schema":{"type":"string","title":"Expert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/experts/admin/appeals/{expert_id}/reject":{"post":{"tags":["Experts"],"summary":"Reject Appeal","description":"Admin: reject an appeal.","operationId":"reject_appeal_api_v1_experts_admin_appeals__expert_id__reject_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"expert_id","in":"path","required":true,"schema":{"type":"string","title":"Expert Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/experts/account":{"delete":{"tags":["Experts"],"summary":"Delete Account","description":"Permanently delete the expert's account and personal data.\n\nRequired by App Store guideline 5.1.1(v) — apps that support account\ncreation must also offer in-app account deletion.\n\nBehavior:\n  - Blocks if there are active chat sessions (must close first)\n  - Blocks if there are pending payouts (must resolve first)\n  - Disconnects + deletes the Stripe Express account\n  - Cancels any open OFFERED assignments\n  - Anonymizes PII fields on the Expert row (email, name, picture,\n    linkedin, skills, schedule). The row itself is retained so that\n    financial audit records (CreditTransaction, completed\n    PayoutRequest) referencing this expert keep their FK integrity\n    for tax/legal retention.\n  - Marks the expert as OFFLINE and clears qualification so they no\n    longer appear in any routing pool.\n  - Best-effort deletes the Auth0 user so they cannot log back in.","operationId":"delete_account_api_v1_experts_account_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/questions/{question_id}":{"get":{"tags":["Questions"],"summary":"Get Question Status","description":"Get question status and check if answer is available","operationId":"get_question_status_api_v1_questions__question_id__get","parameters":[{"name":"question_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Question Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuestionResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/questions/{question_id}/answer":{"get":{"tags":["Questions"],"summary":"Get Question Answer","description":"Get answer for a question if available","operationId":"get_question_answer_api_v1_questions__question_id__answer_get","parameters":[{"name":"question_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Question Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/AnswerResponse"},{"type":"null"}],"title":"Response Get Question Answer Api V1 Questions  Question Id  Answer Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/questions/{question_id}/rate":{"post":{"tags":["Questions"],"summary":"Rate Answer","description":"Rate an answer (1-5 scale)","operationId":"rate_answer_api_v1_questions__question_id__rate_post","parameters":[{"name":"question_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Question Id"}},{"name":"rating","in":"query","required":true,"schema":{"type":"integer","title":"Rating"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/mcp/answers/{question_id}/events":{"get":{"tags":["Events"],"summary":"Answer Events","operationId":"answer_events_api_v1_mcp_answers__question_id__events_get","parameters":[{"name":"question_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Question Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/mcp/chat-sessions/{session_id}/events":{"get":{"tags":["Events"],"summary":"Chat Events","operationId":"chat_events_api_v1_mcp_chat_sessions__session_id__events_get","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Session Id"}},{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/preferences":{"patch":{"tags":["Users"],"summary":"Update User Preferences","description":"Update user preferences.\n\nValidates both the MCP tool-call timeout and the optional custom\nqueue-wait window. When the MCP timeout is lowered, any previously\nstored custom wait window is auto-clamped down to fit the new ceiling\nso the resolved value never exceeds 60% of the session timeout.","operationId":"update_user_preferences_api_v1_users_preferences_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePreferencesRequest"}}},"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/v1/users/plans":{"get":{"tags":["Users"],"summary":"Get Plans","description":"Get available pricing — human subscriptions + agent (x402) per-call.\n\nTwo surfaces in one response:\n  - `subscriptions`: human Stripe subscription tiers (existing)\n  - `x402`: per-call wallet pricing (new, surfaced for agent discovery)\n\nIterates `all_plans()` so the response auto-includes any tier added in\n`subscription_plans.py` without an endpoint edit.","operationId":"get_plans_api_v1_users_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/users/profile":{"get":{"tags":["Users"],"summary":"Get User Profile","description":"Get user profile with API key and credits","operationId":"get_user_profile_api_v1_users_profile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/users/regenerate-api-key":{"post":{"tags":["Users"],"summary":"Regenerate Api Key","description":"Generate a new API key","operationId":"regenerate_api_key_api_v1_users_regenerate_api_key_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/users/questions":{"get":{"tags":["Users"],"summary":"Get User Questions","description":"Get paginated questions asked by this user","operationId":"get_user_questions_api_v1_users_questions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":10,"title":"Size"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/questions/{question_id}":{"get":{"tags":["Users"],"summary":"Get User Question Detail","description":"Get full question detail including answer, expert profile, and chat history","operationId":"get_user_question_detail_api_v1_users_questions__question_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"question_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Question Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/chat-sessions":{"get":{"tags":["Users"],"summary":"Get User Chat Sessions","description":"Get all chat sessions for this user","operationId":"get_user_chat_sessions_api_v1_users_chat_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/users/stats":{"get":{"tags":["Users"],"summary":"Get User Stats","description":"Get usage statistics","operationId":"get_user_stats_api_v1_users_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/users/checkout/subscription":{"post":{"tags":["Users"],"summary":"Create Subscription Checkout","description":"Start a Stripe Checkout session in subscription mode for the chosen tier.","operationId":"create_subscription_checkout_api_v1_users_checkout_subscription_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubscriptionCheckoutRequest"}}},"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/v1/users/billing/portal":{"post":{"tags":["Users"],"summary":"Create Billing Portal","description":"Return a Stripe Customer Portal URL for plan + card management.","operationId":"create_billing_portal_api_v1_users_billing_portal_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/users/billing/settings":{"get":{"tags":["Users"],"summary":"Get Billing Settings","description":"Return the user's current plan + usage + auto-refill configuration.","operationId":"get_billing_settings_api_v1_users_billing_settings_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]},"patch":{"tags":["Users"],"summary":"Update Billing Settings","description":"Update auto-refill toggle and monthly spending cap.","operationId":"update_billing_settings_api_v1_users_billing_settings_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingSettingsUpdate"}}},"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/v1/users/credits/balance":{"get":{"tags":["Users"],"summary":"Get Credit Balance","description":"Get user's current credit balance","operationId":"get_credit_balance_api_v1_users_credits_balance_get","parameters":[{"name":"X-API-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/api-key/expiry":{"patch":{"tags":["Users"],"summary":"Set Api Key Expiry","description":"Set or remove API key expiry. Pass expires_in_days=null to remove.","operationId":"set_api_key_expiry_api_v1_users_api_key_expiry_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SetApiKeyExpiryRequest"}}},"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/v1/users/me/wallet/challenge":{"post":{"tags":["Users"],"summary":"Issue Wallet Challenge","description":"Mint a one-time nonce for the agent to sign.\n\nThe signed message includes the nonce + a short domain string so a\nsignature for one service can't be replayed against another. The\nnonce lives in Redis with a 5-min TTL and is single-use (deleted on\nsuccessful verify).","operationId":"issue_wallet_challenge_api_v1_users_me_wallet_challenge_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletChallengeRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletChallengeResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/me/wallet/transactions":{"post":{"tags":["Users"],"summary":"Get Wallet Transactions","description":"Return the CreditTransaction history for the authenticated wallet.\n\nPOST (not GET) because the body carries a signature blob that wouldn't\nfit cleanly in headers. The endpoint is read-only despite the verb.","operationId":"get_wallet_transactions_api_v1_users_me_wallet_transactions_post","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"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletAuthBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/me/wallet/erase":{"post":{"tags":["Users"],"summary":"Erase Wallet User","description":"GDPR Article 17 erasure for a wallet user.\n\nAnonymizes the wallet_address with a server-salted SHA256 hash so the\nPII (wallet → real-world entity) is severed while the financial audit\ntrail is preserved as aggregate revenue/expert-payout records.\n\nPer Recital 26: data is no longer 'personal' once anonymized, so the\npseudonymized row is no longer subject to erasure requests.","operationId":"erase_wallet_user_api_v1_users_me_wallet_erase_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletAuthBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/me/wallet/subscription/cancel":{"post":{"tags":["Users"],"summary":"Cancel Wallet Subscription","description":"Cancel an active wallet subscription via SIWE.\n\nStatus flips to 'canceled' but `period_end` is preserved so credits\nalready granted remain usable until the period rolls over. The renewal\nworker will skip canceled subs.","operationId":"cancel_wallet_subscription_api_v1_users_me_wallet_subscription_cancel_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WalletAuthBody"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/users/wallet-subscription-tiers":{"get":{"tags":["Users"],"summary":"List Wallet Subscription Tiers","description":"Public list of wallet subscription tiers — used by discovery surfaces\n(for-agents page, llms.txt) and by agents enumerating options.","operationId":"list_wallet_subscription_tiers_api_v1_users_wallet_subscription_tiers_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/users/account":{"delete":{"tags":["Users"],"summary":"Delete Account","description":"Permanently delete the user's account and personal data.\n\nMirrors the expert-side delete endpoint. Behavior:\n  - Blocks if there's an active chat session (must close first).\n  - Cancels any active Stripe subscription (immediate, no proration).\n  - Deletes the Stripe Customer (removes saved payment methods, stops\n    future invoicing).\n  - Revokes the API key (clears api_key + hash + prefix so any agent\n    holding the old key can't make new requests).\n  - Best-effort deletes the Auth0 user so they can't log back in.\n  - Anonymizes the User row's identifying fields. The row itself is\n    retained so CreditTransaction / ChatSession / Question records\n    keep their FK integrity for audit purposes.\n\nReturns 204 on success. The frontend should clear local auth state\nand redirect to the logged-out landing page.","operationId":"delete_account_api_v1_users_account_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/oauth/.well-known/oauth-authorization-server":{"get":{"tags":["OAuth"],"summary":"Oauth Metadata","description":"OAuth 2.0 authorization server metadata (RFC 8414).\n\nMust agree with the root-level handler in main.py — keep both in sync.\nSee main.py oauth_metadata_root for the full rationale on the\nextended field set.","operationId":"oauth_metadata_api_v1_oauth__well_known_oauth_authorization_server_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/oauth/register":{"post":{"tags":["OAuth"],"summary":"Dynamic Client Registration","description":"Dynamic Client Registration (RFC 7591) — required by MCP spec.\n\nRFC 7591 §3.2.1 mandates HTTP 201 Created on success and that the\nresponse echo all registered metadata plus any server-provisioned\nfields (notably client_id_issued_at). Strict DCR clients (e.g.\nSmithery's) reject responses that don't match.","operationId":"dynamic_client_registration_api_v1_oauth_register_post","responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/oauth/authorize":{"get":{"tags":["OAuth"],"summary":"Authorize","description":"Authorize an MCP client against the currently-signed-in app user.\n\nFast path: if the browser sends our `humwork_refresh_token` cookie, the\nuser is already signed into our app — exchange the refresh token at\nAuth0, identify the user, mint an MCP code for THEIR API key, and\nredirect straight to /oauth/success. No Auth0 prompt. This guarantees\n\"whichever account is signed into our app gets the API key.\"\n\nSlow path (no cookie or refresh failed): redirect to Auth0 Universal\nLogin. Auth0 calls back into /oauth/callback which then mints the code.","operationId":"authorize_api_v1_oauth_authorize_get","parameters":[{"name":"client_id","in":"query","required":true,"schema":{"type":"string","title":"Client Id"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}},{"name":"response_type","in":"query","required":true,"schema":{"type":"string","title":"Response Type"}},{"name":"code_challenge","in":"query","required":true,"schema":{"type":"string","title":"Code Challenge"}},{"name":"code_challenge_method","in":"query","required":true,"schema":{"type":"string","title":"Code Challenge Method"}},{"name":"state","in":"query","required":true,"schema":{"type":"string","title":"State"}},{"name":"scope","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/oauth/callback":{"get":{"tags":["OAuth"],"summary":"Oauth Callback","description":"Auth0 redirects here after user authenticates.\nExchange Auth0 code for tokens, then redirect to branded success page.","operationId":"oauth_callback_api_v1_oauth_callback_get","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","title":"Code"}},{"name":"state","in":"query","required":true,"schema":{"type":"string","title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/oauth/token":{"post":{"tags":["OAuth"],"summary":"Token Exchange","description":"Exchange MCP authorization code for access token.\nThe token returned is the user's API key (never expires).","operationId":"token_exchange_api_v1_oauth_token_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/gpt":{"get":{"tags":["GPT"],"summary":"Gpt Info","description":"GET endpoint for ChatGPT to probe","operationId":"gpt_info_api_v1_gpt_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["GPT"],"summary":"Gpt Mcp Endpoint","description":"ChatGPT-specific MCP endpoint — Developer Mode, full tool surface","operationId":"gpt_mcp_endpoint_api_v1_gpt_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/worldid/verify":{"post":{"tags":["World ID"],"summary":"Verify Worldid","description":"Verify World ID proof and link to the current Auth0-authenticated expert.\nExpert must already be logged in via Auth0.","operationId":"verify_worldid_api_v1_worldid_verify_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorldIDProof"}}},"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/v1/worldid/link":{"post":{"tags":["World ID"],"summary":"Link Worldid To Account","description":"Link World ID to an existing expert account","operationId":"link_worldid_to_account_api_v1_worldid_link_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WorldIDProof"}}},"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/v1/worldid/status":{"get":{"tags":["World ID"],"summary":"Get Worldid Status","description":"Check if current expert has World ID verification","operationId":"get_worldid_status_api_v1_worldid_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/webhooks/stripe":{"post":{"tags":["webhooks"],"summary":"Stripe Webhook","description":"Handle Stripe webhook events.\n\nSubscription + auto-refill model:\n- checkout.session.completed (mode=subscription): save customer/sub IDs + PM\n- customer.subscription.updated: handle tier upgrade/downgrade\n- customer.subscription.deleted: cancel — clear active plan\n- invoice.paid: grant monthly block credits + reset usage counters\n- invoice.payment_failed: mark plan inactive, notify user\n- payment_intent.succeeded (auto_refill): informational log only (credits\n  are granted synchronously by the auto_refill service)\n\nExpert payouts:\n- account.updated, payout.paid, payout.failed (unchanged)","operationId":"stripe_webhook_api_v1_webhooks_stripe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/admin/approve-expert/{expert_id}":{"get":{"tags":["admin"],"summary":"Approve Expert","description":"Admin endpoint to approve expert account\nCalled via email link with secret token","operationId":"approve_expert_api_v1_admin_approve_expert__expert_id__get","parameters":[{"name":"expert_id","in":"path","required":true,"schema":{"type":"string","title":"Expert Id"}},{"name":"token","in":"query","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/v1/admin/approve-payout/{request_id}":{"get":{"tags":["admin"],"summary":"Approve Payout","description":"Admin endpoint to approve payout request\nCalled via email link with unique token","operationId":"approve_payout_api_v1_admin_approve_payout__request_id__get","parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}},{"name":"token","in":"query","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/v1/admin/reject-payout/{request_id}":{"get":{"tags":["admin"],"summary":"Reject Payout","description":"Admin endpoint to reject payout request\nCalled via email link with unique token","operationId":"reject_payout_api_v1_admin_reject_payout__request_id__get","parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}},{"name":"token","in":"query","required":true,"schema":{"type":"string","title":"Token"}},{"name":"reason","in":"query","required":false,"schema":{"type":"string","default":"Rejected by admin","title":"Reason"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/qualification-scores":{"get":{"tags":["admin"],"summary":"Get Qualification Scores","description":"Admin endpoint to view all expert qualification scores. Requires admin:access permission.","operationId":"get_qualification_scores_api_v1_admin_qualification_scores_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/admin/payouts":{"get":{"tags":["admin"],"summary":"List Payouts","description":"List all payout requests with expert details. Requires admin:access permission.","operationId":"list_payouts_api_v1_admin_payouts_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status_filter","in":"query","required":false,"schema":{"type":"string","title":"Status Filter"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/payouts/{request_id}/approve":{"post":{"tags":["admin"],"summary":"Approve Payout Admin","description":"Approve a pending payout request. Requires admin:access permission.","operationId":"approve_payout_admin_api_v1_admin_payouts__request_id__approve_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","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/v1/admin/payouts/{request_id}/reject":{"post":{"tags":["admin"],"summary":"Reject Payout Admin","description":"Reject a pending payout request. Requires admin:access permission.","operationId":"reject_payout_admin_api_v1_admin_payouts__request_id__reject_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","title":"Request Id"}},{"name":"reason","in":"query","required":false,"schema":{"type":"string","default":"Rejected by admin","title":"Reason"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/payouts/{request_id}/cancel":{"post":{"tags":["admin"],"summary":"Cancel Payout Admin","description":"Cancel a pending payout request. Requires admin:access permission.","operationId":"cancel_payout_admin_api_v1_admin_payouts__request_id__cancel_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string","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/v1/admin/monitor/stats":{"get":{"tags":["admin-monitor"],"summary":"Get Monitor Stats","description":"One-shot snapshot of fleet + platform stats. Use the WebSocket for live updates.","operationId":"get_monitor_stats_api_v1_admin_monitor_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/admin/monitor/render":{"get":{"tags":["admin-monitor"],"summary":"Get Render Metrics","description":"Proxy the Render Metrics API with caching + graceful fallback.\n\nReturns ``{configured: bool, range_seconds: int, metrics: {...}}``.\nWhen not configured (missing env vars), returns an empty envelope so\nthe frontend can render a placeholder instead of erroring.","operationId":"get_render_metrics_api_v1_admin_monitor_render_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"range","in":"query","required":false,"schema":{"type":"string","default":"1h","title":"Range"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/admin/monitor/neon":{"get":{"tags":["admin-monitor"],"summary":"Get Neon Metrics","description":"Live pg_stat_* + Neon API snapshot.\n\n``slow_queries=true`` additionally runs the pg_stat_statements query\nso the dashboard can show the \"Top slow queries\" panel on demand.","operationId":"get_neon_metrics_api_v1_admin_monitor_neon_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"slow_queries","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Slow Queries"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/qualification/start":{"post":{"tags":["Qualification"],"summary":"Start Qualification Test","description":"Start a qualification test. Expert must be logged in (JWT auth).","operationId":"start_qualification_test_api_v1_qualification_start_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StartTestResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/qualification/answer":{"post":{"tags":["Qualification"],"summary":"Submit Answer","description":"Submit an answer to the current question. Returns next question or results.","operationId":"submit_answer_api_v1_qualification_answer_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitAnswerRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitAnswerResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/qualification/my-result":{"get":{"tags":["Qualification"],"summary":"Get My Result","description":"Get the current expert's most recent completed qualification result.","operationId":"get_my_result_api_v1_qualification_my_result_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestResult"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/qualification/status/{test_id}":{"get":{"tags":["Qualification"],"summary":"Get Test Status","description":"Get the current status and history of a qualification test.","operationId":"get_test_status_api_v1_qualification_status__test_id__get","parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string","title":"Test Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/classify-feedback":{"post":{"tags":["Classify"],"summary":"Classify Feedback","description":"Classify user feedback as rejection or positive/new-work.\n\nCalled by the MCP plugin's mark-user-turn hook (a shell script that\ncurls without auth credentials). Rate-limited per-IP instead of\nper-user because the hook has no access to the MCP server's API key.","operationId":"classify_feedback_api_v1_classify_feedback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClassifyRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClassifyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/voice/transcriptions":{"post":{"tags":["Voice"],"summary":"Transcribe Audio","description":"Proxy audio transcription to Deepgram Nova API.","operationId":"transcribe_audio_api_v1_voice_transcriptions_post","requestBody":{"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_transcribe_audio_api_v1_voice_transcriptions_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/v1/admin/mock-interview/start":{"post":{"tags":["Mock Interview"],"summary":"Start Mock Interview","description":"Start a mock interview for the current admin user.","operationId":"start_mock_interview_api_v1_admin_mock_interview_start_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/admin/mock-interview/answer":{"post":{"tags":["Mock Interview"],"summary":"Submit Mock Answer","description":"Submit an answer in a mock interview.","operationId":"submit_mock_answer_api_v1_admin_mock_interview_answer_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MockAnswerRequest"}}},"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/v1/admin/mock-interview/results":{"get":{"tags":["Mock Interview"],"summary":"Get Mock Results","description":"Get all mock interview results.","operationId":"get_mock_results_api_v1_admin_mock_interview_results_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/admin/mock-interview/results/{test_id}":{"get":{"tags":["Mock Interview"],"summary":"Get Mock Result Detail","description":"Get full detail for a mock interview including all messages and raw grading.","operationId":"get_mock_result_detail_api_v1_admin_mock_interview_results__test_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string","title":"Test Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/deepgram/interview-queue/leave":{"post":{"tags":["Deepgram Voice"],"summary":"Leave Interview Queue","description":"Set a Redis flag so the queue wait loop removes this expert on next check.","operationId":"leave_interview_queue_api_v1_deepgram_interview_queue_leave_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/api/v1/deepgram/interview/active":{"get":{"tags":["Deepgram Voice"],"summary":"Get Active Interview","description":"Return the most recent resumable interview for this expert, if any.\n\nThe frontend uses this on interview-screen mount to offer Resume vs.\nRestart when a session was abandoned mid-interview (tab closed, network\ndrop, agent stall). Real and mock modes are tracked separately.\n\nResumable = IN_PROGRESS (clean abandonment) or ERROR (restarted-over /\nreal error mid-session). The resume architecture exists specifically to\nrescue both. EXPIRED / PASSED / FAILED are terminal and stay terminal.","operationId":"get_active_interview_api_v1_deepgram_interview_active_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"mode","in":"query","required":false,"schema":{"type":"string","default":"real","title":"Mode"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Deepgram Voice"],"summary":"Abandon Active Interview","description":"Wipe the current IN_PROGRESS interview + its messages.\n\nUsed by the \"Restart from scratch\" path so the next session starts\ncleanly without the prior transcript bleeding into the agent's context.\nOnly deletes IN_PROGRESS rows owned by the requesting expert.","operationId":"abandon_active_interview_api_v1_deepgram_interview_active_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"mode","in":"query","required":false,"schema":{"type":"string","default":"real","title":"Mode"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/deepgram/grade-transcript":{"post":{"tags":["Deepgram Voice"],"summary":"Grade Transcript","description":"Grade a mock interview transcript.","operationId":"grade_transcript_api_v1_deepgram_grade_transcript_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GradeTranscriptRequest"}}},"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/v1/deepgram/interview/grade-transcript":{"post":{"tags":["Deepgram Voice"],"summary":"Grade Interview Transcript","description":"Grade a real interview transcript. Updates the expert's profile on pass/fail.","operationId":"grade_interview_transcript_api_v1_deepgram_interview_grade_transcript_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GradeTranscriptRequest"}}},"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/v1/deepgram/interview/{test_id}/result":{"get":{"tags":["Deepgram Voice"],"summary":"Get Interview Result","description":"Poll for a grading result.\n\nUsed by the client as a fallback when the grade-transcript POST response\nwas lost (VPN/middlebox timeout, transient network blip). The client\npolls this endpoint every few seconds; it returns 202 while grading is\nstill in progress, 200 with the final result once the test has reached\na terminal state, 404 if the test doesn't belong to the caller.","operationId":"get_interview_result_api_v1_deepgram_interview__test_id__result_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Test Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/deepgram/interview/regrade/{test_id}":{"post":{"tags":["Deepgram Voice"],"summary":"Regrade Interview Transcript","description":"Re-run grading against the persisted transcript. Allowed when the last\ngrading attempt errored — the transcript is already in the DB so we don't\nneed the client to resubmit it.","operationId":"regrade_interview_transcript_api_v1_deepgram_interview_regrade__test_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"test_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Test Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/client/login":{"post":{"tags":["Auth - Client"],"summary":"Login","description":"Authenticate with email and password via Auth0 ROPG.","operationId":"login_api_v1_auth_client_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/client/signup":{"post":{"tags":["Auth - Client"],"summary":"Signup","description":"Create an Auth0 account and auto-login.","operationId":"signup_api_v1_auth_client_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/client/forgot-password":{"post":{"tags":["Auth - Client"],"summary":"Forgot Password","description":"Request a password reset email from Auth0.","operationId":"forgot_password_api_v1_auth_client_forgot_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/client/refresh":{"post":{"tags":["Auth - Client"],"summary":"Refresh Token","description":"Refresh an access token using the httpOnly refresh token cookie.","operationId":"refresh_token_api_v1_auth_client_refresh_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/client/logout":{"post":{"tags":["Auth - Client"],"summary":"Logout","description":"Clear the refresh token cookie.","operationId":"logout_api_v1_auth_client_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/client/google":{"get":{"tags":["Auth - Client"],"summary":"Google Redirect","description":"Redirect to Auth0's authorize endpoint with Google connection.","operationId":"google_redirect_api_v1_auth_client_google_get","parameters":[{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/client/google/callback":{"post":{"tags":["Auth - Client"],"summary":"Google Callback","description":"Exchange Google OAuth authorization code for tokens.","operationId":"google_callback_api_v1_auth_client_google_callback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleCallbackRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/expert/login":{"post":{"tags":["Auth - Expert"],"summary":"Login","description":"Authenticate with email and password via Auth0 ROPG.","operationId":"login_api_v1_auth_expert_login_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/expert/signup":{"post":{"tags":["Auth - Expert"],"summary":"Signup","description":"Create an Auth0 account and auto-login.","operationId":"signup_api_v1_auth_expert_signup_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/expert/forgot-password":{"post":{"tags":["Auth - Expert"],"summary":"Forgot Password","description":"Request a password reset email from Auth0.","operationId":"forgot_password_api_v1_auth_expert_forgot_password_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/expert/refresh":{"post":{"tags":["Auth - Expert"],"summary":"Refresh Token","description":"Refresh an access token using a refresh token from the request body.","operationId":"refresh_token_api_v1_auth_expert_refresh_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/expert/logout":{"post":{"tags":["Auth - Expert"],"summary":"Logout","description":"No-op for expert app (tokens are cleared client-side from SecureStore).","operationId":"logout_api_v1_auth_expert_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/expert/google":{"get":{"tags":["Auth - Expert"],"summary":"Google Redirect","description":"Redirect to Auth0's authorize endpoint with Google connection.","operationId":"google_redirect_api_v1_auth_expert_google_get","parameters":[{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/expert/google/callback":{"post":{"tags":["Auth - Expert"],"summary":"Google Callback","description":"Exchange Google OAuth authorization code for tokens.","operationId":"google_callback_api_v1_auth_expert_google_callback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleCallbackRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/expert/google/mobile":{"get":{"tags":["Auth - Expert"],"summary":"Google Mobile Redirect","description":"Redirect to Auth0 for Google login, with callback pointing back to the backend.","operationId":"google_mobile_redirect_api_v1_auth_expert_google_mobile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/expert/google/mobile-callback":{"get":{"tags":["Auth - Expert"],"summary":"Google Mobile Callback","description":"Auth0 redirects here after Google login. Exchange code, then redirect to the app scheme with tokens.","operationId":"google_mobile_callback_api_v1_auth_expert_google_mobile_callback_get","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","title":"Code"}},{"name":"state","in":"query","required":false,"schema":{"type":"string","default":"","title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/expert/apple":{"get":{"tags":["Auth - Expert"],"summary":"Apple Redirect","description":"Redirect to Auth0's authorize endpoint with the Apple connection.","operationId":"apple_redirect_api_v1_auth_expert_apple_get","parameters":[{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/expert/apple/callback":{"post":{"tags":["Auth - Expert"],"summary":"Apple Callback","description":"Exchange Apple Sign-In authorization code for tokens.\n\nReuses GoogleCallbackRequest because the wire shape (code + redirect_uri)\nis identical — Auth0 abstracts the provider differences server-side.","operationId":"apple_callback_api_v1_auth_expert_apple_callback_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GoogleCallbackRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/auth/expert/apple/mobile":{"get":{"tags":["Auth - Expert"],"summary":"Apple Mobile Redirect","description":"Redirect to Auth0 for Apple login, with callback pointing back to the backend.","operationId":"apple_mobile_redirect_api_v1_auth_expert_apple_mobile_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/auth/expert/apple/mobile-callback":{"get":{"tags":["Auth - Expert"],"summary":"Apple Mobile Callback","description":"Auth0 redirects here after Apple login. Exchange code, then redirect to the app scheme with tokens.","operationId":"apple_mobile_callback_api_v1_auth_expert_apple_mobile_callback_get","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","title":"Code"}},{"name":"state","in":"query","required":false,"schema":{"type":"string","default":"","title":"State"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v1/email/unsubscribe":{"get":{"tags":["Email Preferences"],"summary":"Unsubscribe Get","operationId":"unsubscribe_get_api_v1_email_unsubscribe_get","parameters":[{"name":"token","in":"query","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":["Email Preferences"],"summary":"Unsubscribe Post","description":"RFC 8058 one-click endpoint. Mail clients POST here directly.\n\nMust respond 2xx with no body on success; no HTML rendering needed.","operationId":"unsubscribe_post_api_v1_email_unsubscribe_post","parameters":[{"name":"token","in":"query","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"}}}}}}},"/health/detailed":{"get":{"summary":"Health Detailed","description":"Detailed health information including recovery logs and circuit breaker states.","operationId":"health_detailed_health_detailed_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Liveness","description":"Liveness: is the server process running? Returns 200 if alive.","operationId":"liveness_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/ready":{"get":{"summary":"Readiness","description":"Readiness: is the server ready to accept traffic? Checks PostgreSQL, Redis, WebSocket. Returns 200 if ready, 503 otherwise.","operationId":"readiness_ready_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/metrics":{"get":{"summary":"Metrics","description":"Prometheus-compatible metrics endpoint for scraping and alerting.\n\nThis endpoint exposes metrics in Prometheus format that can be:\n- Scraped by Prometheus server\n- Visualized in Grafana dashboards\n- Used for alerting rules\n\nExample Prometheus scrape config:\n  - job_name: 'humwork-backend'\n    scrape_interval: 30s\n    metrics_path: '/metrics'\n    static_configs:\n      - targets: ['localhost:8000']","operationId":"metrics_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/v1/mcp/timeout/metrics":{"get":{"summary":"Timeout Metrics","description":"Get timeout metrics and statistics","operationId":"timeout_metrics_api_v1_mcp_timeout_metrics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/":{"get":{"summary":"Root","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/debug/pool-status":{"get":{"summary":"Debug Pool Status","description":"Monitor database connection pool health","operationId":"debug_pool_status_debug_pool_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/.well-known/oauth-protected-resource/{path}":{"get":{"summary":"Protected Resource Metadata","description":"Protected Resource Metadata (RFC 9728) - tells clients how to use tokens with this resource.\n\nOpenAI App Directory's MCP discovery scanner requires `scopes_supported`\non this response — without it, scan returns \"unsupported OAuth config type\".","operationId":"protected_resource_metadata__well_known_oauth_protected_resource__path__get","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/oauth-protected-resource":{"get":{"summary":"Protected Resource Metadata","description":"Protected Resource Metadata (RFC 9728) - tells clients how to use tokens with this resource.\n\nOpenAI App Directory's MCP discovery scanner requires `scopes_supported`\non this response — without it, scan returns \"unsupported OAuth config type\".","operationId":"protected_resource_metadata__well_known_oauth_protected_resource_get","parameters":[{"name":"path","in":"query","required":false,"schema":{"type":"string","default":"","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/oauth-authorization-server/{path}":{"get":{"summary":"Oauth Metadata Root","description":"OAuth 2.0 Authorization Server Metadata (RFC 8414).\n\nPure OAuth 2.0 only — no OIDC fields. We previously included\nsubject_types_supported / op_policy_uri / op_tos_uri (all OIDC\nDiscovery fields), which signaled to OpenAI's MCP App Directory\nscanner that we were an OpenID Connect server. The scanner then\nfetched /.well-known/openid-configuration, got a 404, and\nclassified us as 'unsupported OAuth config type' (visible in\nRender logs around 2026-05-07 03:28 UTC: 3x consecutive\nopenid-configuration 404s during a failed scan).","operationId":"oauth_metadata_root__well_known_oauth_authorization_server__path__get","parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/oauth-authorization-server":{"get":{"summary":"Oauth Metadata Root","description":"OAuth 2.0 Authorization Server Metadata (RFC 8414).\n\nPure OAuth 2.0 only — no OIDC fields. We previously included\nsubject_types_supported / op_policy_uri / op_tos_uri (all OIDC\nDiscovery fields), which signaled to OpenAI's MCP App Directory\nscanner that we were an OpenID Connect server. The scanner then\nfetched /.well-known/openid-configuration, got a 404, and\nclassified us as 'unsupported OAuth config type' (visible in\nRender logs around 2026-05-07 03:28 UTC: 3x consecutive\nopenid-configuration 404s during a failed scan).","operationId":"oauth_metadata_root__well_known_oauth_authorization_server_get","parameters":[{"name":"path","in":"query","required":false,"schema":{"type":"string","default":"","title":"Path"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/openai-apps-challenge":{"get":{"summary":"Openai Apps Challenge","description":"OpenAI App Directory domain verification.\n\nServes the token OpenAI gives us in the app submission flow. Set the\ntoken via the OPENAI_APPS_CHALLENGE_TOKEN env var on Render — no need\nto commit it. Returns plain text per the well-known challenge convention.","operationId":"openai_apps_challenge__well_known_openai_apps_challenge_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/.well-known/mcp/server-card.json":{"get":{"summary":"Mcp Server Card","description":"Static MCP server card per SEP-1649.\n\nSmithery and other MCP discovery clients read this file (not the\nJSON-RPC initialize response) to score server metadata: description,\nhomepage, icon. Kept as a static dict so it serves without OAuth and\nwithout exercising the JSON-RPC handler.","operationId":"mcp_server_card__well_known_mcp_server_card_json_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AnswerCreate":{"properties":{"content":{"type":"string","minLength":10,"title":"Content"}},"type":"object","required":["content"],"title":"AnswerCreate"},"AnswerResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"content":{"type":"string","title":"Content"},"expert_id":{"type":"string","format":"uuid","title":"Expert Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","content","expert_id","created_at"],"title":"AnswerResponse"},"BillingSettingsUpdate":{"properties":{"auto_refill_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Auto Refill Enabled"},"monthly_cap_cents":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Monthly Cap Cents"}},"type":"object","title":"BillingSettingsUpdate"},"Body_transcribe_audio_api_v1_voice_transcriptions_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_transcribe_audio_api_v1_voice_transcriptions_post"},"Body_upload_profile_picture_api_v1_experts_profile_picture_post":{"properties":{"file":{"type":"string","contentMediaType":"application/octet-stream","title":"File"}},"type":"object","required":["file"],"title":"Body_upload_profile_picture_api_v1_experts_profile_picture_post"},"ClassifyRequest":{"properties":{"message":{"type":"string","maxLength":5000,"minLength":1,"title":"Message"}},"type":"object","required":["message"],"title":"ClassifyRequest"},"ClassifyResponse":{"properties":{"is_rejection":{"type":"boolean","title":"Is Rejection"}},"type":"object","required":["is_rejection"],"title":"ClassifyResponse"},"ExpertProfile":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"type":"string","title":"Email"},"skills":{"items":{"type":"string"},"type":"array","title":"Skills"},"rating":{"type":"number","title":"Rating"},"total_answers":{"type":"integer","title":"Total Answers"},"credits_earned":{"type":"integer","title":"Credits Earned"},"status":{"type":"string","title":"Status"},"worldid_nullifier":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Worldid Nullifier"},"worldid_verified":{"type":"boolean","title":"Worldid Verified","default":false},"stripe_account_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stripe Account Id"},"stripe_onboarding_complete":{"type":"boolean","title":"Stripe Onboarding Complete","default":false},"hourly_rate":{"type":"integer","title":"Hourly Rate","default":60},"work_schedule":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Work Schedule"},"schedule_paused":{"type":"boolean","title":"Schedule Paused","default":false},"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"profile_picture_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Picture Url"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"}},"type":"object","required":["id","email","skills","rating","total_answers","credits_earned","status"],"title":"ExpertProfile"},"ExpertQuestionView":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"title":{"type":"string","title":"Title"},"summary":{"type":"string","title":"Summary"},"detected_skills":{"items":{"type":"string"},"type":"array","title":"Detected Skills"},"urgency":{"type":"string","title":"Urgency"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"time_remaining":{"type":"number","title":"Time Remaining"},"offered_at":{"type":"string","format":"date-time","title":"Offered At"},"timeout_window":{"type":"integer","title":"Timeout Window"}},"type":"object","required":["id","title","summary","detected_skills","urgency","created_at","time_remaining","offered_at","timeout_window"],"title":"ExpertQuestionView"},"ExpertStats":{"properties":{"total_earned":{"type":"integer","title":"Total Earned"},"questions_answered":{"type":"integer","title":"Questions Answered"},"average_rating":{"type":"number","title":"Average Rating"},"response_time_avg":{"type":"integer","title":"Response Time Avg"},"earnings_this_month":{"type":"integer","title":"Earnings This Month"},"rating_distribution":{"additionalProperties":{"type":"integer"},"type":"object","title":"Rating Distribution"}},"type":"object","required":["total_earned","questions_answered","average_rating","response_time_avg","earnings_this_month","rating_distribution"],"title":"ExpertStats"},"FocusLossEvent":{"properties":{"timestamp":{"type":"string","title":"Timestamp"},"duration_seconds":{"type":"number","title":"Duration Seconds"}},"type":"object","required":["timestamp","duration_seconds"],"title":"FocusLossEvent"},"ForgotPasswordRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"ForgotPasswordRequest"},"GoogleCallbackRequest":{"properties":{"code":{"type":"string","title":"Code"},"redirect_uri":{"type":"string","title":"Redirect Uri"}},"type":"object","required":["code","redirect_uri"],"title":"GoogleCallbackRequest"},"GradeTranscriptRequest":{"properties":{"test_id":{"type":"string","title":"Test Id"},"transcript":{"items":{"$ref":"#/components/schemas/TranscriptMessage"},"type":"array","title":"Transcript"},"domain":{"type":"string","title":"Domain","default":"software"}},"type":"object","required":["test_id","transcript"],"title":"GradeTranscriptRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"InitTimezoneRequest":{"properties":{"timezone":{"type":"string","title":"Timezone"}},"type":"object","required":["timezone"],"title":"InitTimezoneRequest"},"LoginRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"LoginRequest"},"MockAnswerRequest":{"properties":{"test_id":{"type":"string","title":"Test Id"},"answer":{"type":"string","title":"Answer"},"time_to_respond_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Time To Respond Seconds"},"focus_loss_events":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Focus Loss Events"},"paste_detected":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Paste Detected"}},"type":"object","required":["test_id","answer"],"title":"MockAnswerRequest"},"PayoutRequest":{"properties":{"amount_credits":{"type":"integer","title":"Amount Credits"}},"type":"object","required":["amount_credits"],"title":"PayoutRequest"},"ProfileUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"profile_picture_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Profile Picture Url"},"linkedin_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Linkedin Url"}},"type":"object","title":"ProfileUpdate"},"QuestionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"title":{"type":"string","title":"Title"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"answer_available":{"type":"boolean","title":"Answer Available","default":false}},"type":"object","required":["id","title","status","created_at"],"title":"QuestionResponse"},"RefreshRequest":{"properties":{"refresh_token":{"type":"string","title":"Refresh Token"}},"type":"object","required":["refresh_token"],"title":"RefreshRequest"},"SetApiKeyExpiryRequest":{"properties":{"expires_in_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Expires In Days"}},"type":"object","title":"SetApiKeyExpiryRequest"},"SignupRequest":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"password":{"type":"string","title":"Password"}},"type":"object","required":["email","password"],"title":"SignupRequest"},"SkillsUpdate":{"properties":{"skills":{"items":{"type":"string"},"type":"array","title":"Skills"}},"type":"object","required":["skills"],"title":"SkillsUpdate"},"StartTestResponse":{"properties":{"test_id":{"type":"string","title":"Test Id"},"test_token":{"type":"string","title":"Test Token"},"first_question":{"type":"string","title":"First Question"},"max_questions":{"type":"integer","title":"Max Questions"},"resumed":{"type":"boolean","title":"Resumed","default":false},"questions_asked":{"type":"integer","title":"Questions Asked","default":0}},"type":"object","required":["test_id","test_token","first_question","max_questions"],"title":"StartTestResponse"},"StatusUpdate":{"properties":{"status":{"type":"string","title":"Status"},"pause_schedule":{"type":"boolean","title":"Pause Schedule","default":false}},"type":"object","required":["status"],"title":"StatusUpdate"},"StripeConnectRequest":{"properties":{"country":{"type":"string","title":"Country","default":"US"}},"type":"object","title":"StripeConnectRequest"},"SubmitAnswerRequest":{"properties":{"answer":{"type":"string","title":"Answer"},"time_to_respond_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Time To Respond Seconds"},"focus_loss_events":{"anyOf":[{"items":{"$ref":"#/components/schemas/FocusLossEvent"},"type":"array"},{"type":"null"}],"title":"Focus Loss Events"},"paste_detected":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Paste Detected"}},"type":"object","required":["answer"],"title":"SubmitAnswerRequest"},"SubmitAnswerResponse":{"properties":{"next_question":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Question"},"is_complete":{"type":"boolean","title":"Is Complete"},"question_number":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Question Number"},"result":{"anyOf":[{"$ref":"#/components/schemas/TestResult"},{"type":"null"}]}},"type":"object","required":["is_complete"],"title":"SubmitAnswerResponse"},"SubscriptionCheckoutRequest":{"properties":{"tier":{"type":"string","title":"Tier"}},"type":"object","required":["tier"],"title":"SubscriptionCheckoutRequest"},"TestResult":{"properties":{"passed":{"type":"boolean","title":"Passed"},"overall_score":{"type":"number","title":"Overall Score"},"dimensions":{"additionalProperties":{"type":"integer"},"type":"object","title":"Dimensions"},"extracted_skills":{"items":{"type":"string"},"type":"array","title":"Extracted Skills"},"summary":{"type":"string","title":"Summary"},"concerns":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Concerns"},"status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"},"test_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Test Id"}},"type":"object","required":["passed","overall_score","dimensions","extracted_skills","summary"],"title":"TestResult"},"TestStatusResponse":{"properties":{"test_id":{"type":"string","title":"Test Id"},"status":{"type":"string","title":"Status"},"questions_asked":{"type":"integer","title":"Questions Asked"},"max_questions":{"type":"integer","title":"Max Questions"},"messages":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Messages"},"result":{"anyOf":[{"$ref":"#/components/schemas/TestResult"},{"type":"null"}]}},"type":"object","required":["test_id","status","questions_asked","max_questions","messages"],"title":"TestStatusResponse"},"TranscriptMessage":{"properties":{"role":{"type":"string","title":"Role"},"content":{"type":"string","title":"Content"},"time_to_respond_seconds":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Time To Respond Seconds"},"focus_loss_events":{"anyOf":[{"items":{},"type":"array"},{"type":"null"}],"title":"Focus Loss Events"}},"type":"object","required":["role","content"],"title":"TranscriptMessage"},"UpdatePreferencesRequest":{"properties":{"mcp_timeout_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Mcp Timeout Seconds"},"queue_wait_custom":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Queue Wait Custom"},"queue_wait_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Queue Wait Seconds"}},"type":"object","title":"UpdatePreferencesRequest"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"WalletAuthBody":{"properties":{"wallet_address":{"type":"string","title":"Wallet Address"},"nonce":{"type":"string","title":"Nonce"},"signature":{"type":"string","title":"Signature"}},"type":"object","required":["wallet_address","nonce","signature"],"title":"WalletAuthBody"},"WalletChallengeRequest":{"properties":{"wallet_address":{"type":"string","title":"Wallet Address"}},"type":"object","required":["wallet_address"],"title":"WalletChallengeRequest"},"WalletChallengeResponse":{"properties":{"nonce":{"type":"string","title":"Nonce"},"message":{"type":"string","title":"Message"},"expires_at":{"type":"string","title":"Expires At"}},"type":"object","required":["nonce","message","expires_at"],"title":"WalletChallengeResponse"},"WorkScheduleUpdate":{"properties":{"timezone":{"type":"string","title":"Timezone"},"monday":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Monday"},"tuesday":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Tuesday"},"wednesday":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Wednesday"},"thursday":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Thursday"},"friday":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Friday"},"saturday":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Saturday"},"sunday":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Sunday"}},"type":"object","required":["timezone"],"title":"WorkScheduleUpdate"},"WorldIDProof":{"properties":{"merkle_root":{"type":"string","title":"Merkle Root"},"nullifier_hash":{"type":"string","title":"Nullifier Hash"},"proof":{"type":"string","title":"Proof"},"verification_level":{"type":"string","title":"Verification Level"}},"type":"object","required":["merkle_root","nullifier_hash","proof","verification_level"],"title":"WorldIDProof"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}