{"openapi":"3.1.0","info":{"title":"Code of Paper Dev API","version":"0.1.0"},"paths":{"/search":{"get":{"summary":"Search","operationId":"search_search_get","parameters":[{"name":"query","in":"query","required":false,"schema":{"type":"string","description":"Search query (e.g. paper title or topic)","default":"","title":"Query"},"description":"Search query (e.g. paper title or topic)"},{"name":"abstract","in":"query","required":false,"schema":{"type":"string","description":"Paper abstract (optional)","default":"","title":"Abstract"},"description":"Paper abstract (optional)"},{"name":"arxiv_id","in":"query","required":false,"schema":{"type":"string","description":"arXiv ID (optional)","default":"","title":"Arxiv Id"},"description":"arXiv ID (optional)"},{"name":"k","in":"query","required":false,"schema":{"type":"integer","description":"Number of top repos to return","default":3,"title":"K"},"description":"Number of top repos to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/debug":{"get":{"summary":"Debug Search","description":"Debug endpoint for developers to analyze scoring decisions.","operationId":"debug_search_debug_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string","description":"Search query for debugging","title":"Query"},"description":"Search query for debugging"},{"name":"arxiv_id","in":"query","required":false,"schema":{"type":"string","description":"arXiv ID (optional)","default":"","title":"Arxiv Id"},"description":"arXiv ID (optional)"},{"name":"include_debug","in":"query","required":false,"schema":{"type":"boolean","description":"Include detailed debug information","default":true,"title":"Include Debug"},"description":"Include detailed debug information"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/{paper_id}/refresh":{"post":{"summary":"Refresh Paper Repos","description":"[PREMIUM] Re-run live GitHub search and scoring for a paper.\n\nThis endpoint performs a fresh search on GitHub and re-scores all\nrepositories against the paper. Results are cached for future use.\n\nRequires premium subscription.","operationId":"refresh_paper_repos_papers__paper_id__refresh_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/search/live":{"post":{"summary":"Search Live","description":"[PREMIUM] Perform live ArXiv + GitHub search (not cached).\n\nThis endpoint searches ArXiv in real-time for papers matching the query,\nthen searches GitHub for implementations. Use for finding very recent\npapers not yet in our cache.\n\nRequires premium subscription.","operationId":"search_live_search_live_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string","description":"Search query","title":"Query"},"description":"Search query"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/login":{"get":{"tags":["authentication"],"summary":"Login","description":"Initiate GitHub OAuth login flow.\n\nReturns redirect to GitHub authorization page.","operationId":"login_auth_login_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/auth/callback":{"get":{"tags":["authentication"],"summary":"Oauth Callback","description":"Handle GitHub OAuth callback.\n\nExchange authorization code for access token, fetch user info,\nand create/update user in database.\n\nReturns JWT tokens for authentication.","operationId":"oauth_callback_auth_callback_get","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","description":"Authorization code from GitHub","title":"Code"},"description":"Authorization code from GitHub"},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"State parameter for CSRF protection","title":"State"},"description":"State parameter for CSRF protection"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/exchange":{"post":{"tags":["authentication"],"summary":"Exchange Auth Code","description":"Exchange a short-lived authorization code for JWT tokens.\n\nThe frontend calls this endpoint server-to-server after receiving\nthe authorization code via redirect. The code is single-use and\nexpires after 60 seconds.","operationId":"exchange_auth_code_auth_exchange_post","parameters":[{"name":"code","in":"query","required":true,"schema":{"type":"string","description":"Authorization code from OAuth callback","title":"Code"},"description":"Authorization code from OAuth callback"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/success":{"get":{"tags":["authentication"],"summary":"Auth Success","description":"Display authentication success page with access token.\n\nThis page is shown after successful GitHub OAuth callback.\nDisplays the access token and redirects to the frontend.","operationId":"auth_success_auth_success_get","parameters":[{"name":"access_token","in":"query","required":true,"schema":{"type":"string","title":"Access Token"}},{"name":"user_name","in":"query","required":true,"schema":{"type":"string","title":"User Name"}},{"name":"user_username","in":"query","required":true,"schema":{"type":"string","title":"User Username"}},{"name":"user_avatar","in":"query","required":false,"schema":{"type":"string","default":"","title":"User Avatar"}}],"responses":{"200":{"description":"Successful Response","content":{"text/html":{"schema":{"type":"string"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/me":{"get":{"tags":["authentication"],"summary":"Get Current User Info","description":"Get current authenticated user information.\n\nRequires valid JWT token in Authorization header.","operationId":"get_current_user_info_auth_me_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}}},"security":[{"HTTPBearer":[]}]}},"/auth/logout":{"post":{"tags":["authentication"],"summary":"Logout","description":"Logout current user by invalidating their session.\n\nRequires valid JWT token in Authorization header.\nRate limited to 10 requests per minute.","operationId":"logout_auth_logout_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/auth/refresh":{"post":{"tags":["authentication"],"summary":"Refresh Access Token","description":"Refresh expired access token using refresh token.\n\nArgs:\n    refresh_token: Valid refresh token\n\nReturns:\n    New access token and refresh token\n\nRate limited to 20 requests per minute.","operationId":"refresh_access_token_auth_refresh_post","parameters":[{"name":"refresh_token","in":"query","required":true,"schema":{"type":"string","title":"Refresh Token"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/sessions":{"get":{"tags":["authentication"],"summary":"Get User Sessions","description":"Get all active sessions for current user.\n\nReturns detailed information about each session including:\n- Session ID\n- Creation time\n- Expiration time\n- Last activity time\n- IP address\n- User agent (browser/device info)\n- Whether it's the current session","operationId":"get_user_sessions_auth_sessions_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/auth/sessions/cleanup":{"delete":{"tags":["authentication"],"summary":"Cleanup Expired Sessions","description":"Clean up expired sessions for current user.\n\nDeletes all sessions that have passed their expiration time.","operationId":"cleanup_expired_sessions_auth_sessions_cleanup_delete","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/auth/sessions/{session_id}":{"delete":{"tags":["authentication"],"summary":"Revoke Session","description":"Revoke a specific session.","operationId":"revoke_session_auth_sessions__session_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth/sessions/logout-all":{"post":{"tags":["authentication"],"summary":"Logout All Sessions","description":"Logout from all devices by invalidating all sessions.\n\nUseful if user suspects their account has been compromised.","operationId":"logout_all_sessions_auth_sessions_logout_all_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/users/{username}":{"get":{"tags":["users"],"summary":"Get User By Username","description":"Get public user profile by GitHub username.","operationId":"get_user_by_username_users__username__get","parameters":[{"name":"username","in":"path","required":true,"schema":{"type":"string","title":"Username"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me":{"patch":{"tags":["users"],"summary":"Update Current User","description":"Update current user's profile.","operationId":"update_current_user_users_me_patch","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserUpdateRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/users/me/badges":{"get":{"tags":["users"],"summary":"Get Current User Badges","description":"Get current user's badges.","operationId":"get_current_user_badges_users_me_badges_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/users/me/follows":{"get":{"tags":["users"],"summary":"Get Current User Follows","description":"Get items followed by current user.\n\nArgs:\n    follow_type: Filter by type (paper, repository, user)","operationId":"get_current_user_follows_users_me_follows_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"follow_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(paper|repository|user)$"},{"type":"null"}],"title":"Follow Type"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["users"],"summary":"Follow Item","description":"Follow a paper, repository, or user.","operationId":"follow_item_users_me_follows_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"follow_type","in":"query","required":true,"schema":{"type":"string","pattern":"^(paper|repository|user)$","title":"Follow Type"}},{"name":"target_id","in":"query","required":true,"schema":{"type":"string","description":"Paper ID, repo full_name, or user ID","title":"Target Id"},"description":"Paper ID, repo full_name, or user ID"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me/follows/{follow_id}":{"delete":{"tags":["users"],"summary":"Unfollow Item","description":"Unfollow an item.","operationId":"unfollow_item_users_me_follows__follow_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"follow_id","in":"path","required":true,"schema":{"type":"string","title":"Follow Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me/saved-searches":{"get":{"tags":["users"],"summary":"Get Saved Searches","description":"Get current user's saved searches.","operationId":"get_saved_searches_users_me_saved_searches_get","security":[{"HTTPBearer":[]}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}},"post":{"tags":["users"],"summary":"Save Search","description":"Save a search query with optional alert.","operationId":"save_search_users_me_saved_searches_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"name","in":"query","required":true,"schema":{"type":"string","maxLength":255,"title":"Name"}},{"name":"query","in":"query","required":true,"schema":{"type":"string","title":"Query"}},{"name":"is_alert","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Is Alert"}},{"name":"alert_frequency","in":"query","required":false,"schema":{"type":"string","pattern":"^(instant|daily|weekly)$","default":"daily","title":"Alert Frequency"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me/saved-searches/{search_id}":{"delete":{"tags":["users"],"summary":"Delete Saved Search","description":"Delete a saved search.","operationId":"delete_saved_search_users_me_saved_searches__search_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"search_id","in":"path","required":true,"schema":{"type":"string","title":"Search Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/":{"get":{"tags":["users"],"summary":"List Users","description":"List all users (admin only).","operationId":"list_users_users__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"skip","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Skip"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UserResponse"},"title":"Response List Users Users  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/admin/list":{"get":{"tags":["users"],"summary":"Admin List Users","description":"List all users with admin-level detail (admin only).\nReturns extended user info including activity counts.","operationId":"admin_list_users_users_admin_list_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"skip","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Skip"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search by username or display name","title":"Search"},"description":"Search by username or display name"},{"name":"user_type","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by user type","title":"User Type"},"description":"Filter by user type"},{"name":"sort_by","in":"query","required":false,"schema":{"type":"string","description":"Sort field","default":"created_at","title":"Sort By"},"description":"Sort field"},{"name":"sort_order","in":"query","required":false,"schema":{"type":"string","pattern":"^(asc|desc)$","default":"desc","title":"Sort Order"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/{user_id}/verify":{"patch":{"tags":["users"],"summary":"Verify User As Author","description":"Verify a user as a paper author (admin only).","operationId":"verify_user_as_author_users__user_id__verify_patch","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"paper_ids","in":"query","required":true,"schema":{"type":"array","items":{"type":"string"},"description":"List of paper IDs to verify","title":"Paper Ids"},"description":"List of paper IDs to verify"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/{user_id}/ban":{"post":{"tags":["users"],"summary":"Ban User","description":"Ban a user (admin only).","operationId":"ban_user_users__user_id__ban_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"user_id","in":"path","required":true,"schema":{"type":"string","title":"User Id"}},{"name":"reason","in":"query","required":true,"schema":{"type":"string","maxLength":500,"title":"Reason"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/votes/paper/{paper_id}/repo/{owner}/{repo_name}":{"post":{"tags":["votes"],"summary":"Vote On Paper Repo","description":"Vote on a paper-repository pair.\n- If user hasn't voted: create new vote\n- If user voted same type: remove vote (toggle off)\n- If user voted different type: change vote","operationId":"vote_on_paper_repo_votes_paper__paper_id__repo__owner___repo_name__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}},{"name":"owner","in":"path","required":true,"schema":{"type":"string","title":"Owner"}},{"name":"repo_name","in":"path","required":true,"schema":{"type":"string","title":"Repo Name"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoteRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["votes"],"summary":"Remove Vote","description":"Remove a user's vote from a paper-repository pair.","operationId":"remove_vote_votes_paper__paper_id__repo__owner___repo_name__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}},{"name":"owner","in":"path","required":true,"schema":{"type":"string","title":"Owner"}},{"name":"repo_name","in":"path","required":true,"schema":{"type":"string","title":"Repo Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["votes"],"summary":"Get Votes","description":"Get vote counts for a specific paper-repository pair.","operationId":"get_votes_votes_paper__paper_id__repo__owner___repo_name__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}},{"name":"owner","in":"path","required":true,"schema":{"type":"string","title":"Owner"}},{"name":"repo_name","in":"path","required":true,"schema":{"type":"string","title":"Repo Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/votes/batch":{"post":{"tags":["votes"],"summary":"Get Batch Votes","description":"Get vote counts for multiple paper-repository pairs.\nReturns vote counts and user's vote status for each pair.","operationId":"get_batch_votes_votes_batch_post","requestBody":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/BatchVoteRequest"},"type":"array","title":"Batch Request"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchVoteResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/papers/sitemap-ids":{"get":{"tags":["papers"],"summary":"Get Sitemap Ids","description":"Return paper IDs and last-modified dates in batches for sitemap generation.\nUsed internally by the frontend sitemap builder.","operationId":"get_sitemap_ids_papers_sitemap_ids_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Page number (0-indexed)","default":0,"title":"Page"},"description":"Page number (0-indexed)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Sitemap Ids Papers Sitemap Ids Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/random":{"get":{"tags":["papers"],"summary":"Get Random Paper","description":"Return a random interesting paper for the Explore feature.\nQuality filters ensure users discover good papers.","operationId":"get_random_paper_papers_random_get","parameters":[{"name":"quality","in":"query","required":false,"schema":{"type":"string","description":"Quality filter: high (stars>=10), medium (has code), any","default":"high","title":"Quality"},"description":"Quality filter: high (stars>=10), medium (has code), any"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/search":{"get":{"tags":["papers"],"summary":"Search Papers","description":"Search papers using PostgreSQL full-text search on cached papers.\n\nReturns papers from cache that match the query.\nUses PostgreSQL ts_rank for relevance scoring.\n\nExample:\n    GET /papers/search?query=face+detection&limit=20\n\nReturns:\n    {\n        \"query\": \"face detection\",\n        \"count\": 20,\n        \"papers\": [\n            {\n                \"id\": \"2301.12345\",\n                \"title\": \"...\",\n                \"authors\": [\"...\"],\n                \"summary\": \"...\",\n                \"published_date\": \"2023-01-25T00:00:00\",\n                \"categories\": [\"cs.CV\", \"cs.AI\"],\n                \"url\": \"https://arxiv.org/abs/2301.12345\",\n                \"similarity_score\": 0.85,\n                \"has_repos\": true,\n                \"repo_count\": 3,\n                \"has_official_repo\": true\n            },\n            ...\n        ],\n        \"source\": \"cache\"\n    }","operationId":"search_papers_papers_search_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"query","in":"query","required":true,"schema":{"type":"string","minLength":1,"description":"Search query (keywords or phrase). Use quotes for exact phrases: \"face recognition\"","title":"Query"},"description":"Search query (keywords or phrase). Use quotes for exact phrases: \"face recognition\""},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Maximum number of results","default":20,"title":"Limit"},"description":"Maximum number of results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Offset for pagination","default":0,"title":"Offset"},"description":"Offset for pagination"},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["relevant","recent","has_code","trending"],"type":"string","description":"Sort order: relevant, recent, has_code, trending","default":"relevant","title":"Sort By"},"description":"Sort order: relevant, recent, has_code, trending"},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":2100,"minimum":1990},{"type":"null"}],"description":"Restrict to a single publication year (inclusive).","title":"Year"},"description":"Restrict to a single publication year (inclusive)."},{"name":"after","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Only papers published on/after this date (YYYY-MM-DD).","title":"After"},"description":"Only papers published on/after this date (YYYY-MM-DD)."},{"name":"before","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Only papers published on/before this date (YYYY-MM-DD).","title":"Before"},"description":"Only papers published on/before this date (YYYY-MM-DD)."},{"name":"venue","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Restrict to a conference. Accepts a series (e.g. 'neurips'), a specific conference id (e.g. 'neurips2024'), or a substring of the conference name. Case-insensitive.","title":"Venue"},"description":"Restrict to a conference. Accepts a series (e.g. 'neurips'), a specific conference id (e.g. 'neurips2024'), or a substring of the conference name. Case-insensitive."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Search Papers Papers Search Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/suggest":{"get":{"tags":["papers"],"summary":"Suggest Papers","description":"Fast autocomplete suggestions for paper titles.\n\nUses PostgreSQL full-text search with prefix matching via the GIN-indexed\nsearch_vector column (~2ms response time). Each word in the query is\ntreated as a prefix.\n\nReturns minimal data for quick rendering: id, arxiv_id, title, has_repos.\n\nDesigned for 100k+ papers with sub-10ms response times.","operationId":"suggest_papers_papers_suggest_get","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string","minLength":2,"description":"Search prefix (minimum 2 chars)","title":"Q"},"description":"Search prefix (minimum 2 chars)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":15,"minimum":1,"description":"Max suggestions","default":6,"title":"Limit"},"description":"Max suggestions"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Suggest Papers Papers Suggest Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/health":{"get":{"tags":["papers"],"summary":"Health Check","description":"Check health of paper search service.\n\nVerifies:\n- Database connection works\n- Paper count\n- Optional: FAISS/Ollama for premium features\n\nReturns:\n    {\n        \"status\": \"healthy\",\n        \"paper_count\": 1234,\n        \"papers_with_repos\": 567\n    }","operationId":"health_check_papers_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Health Check Papers Health Get"}}}}}}},"/papers/conference/{conference_id}":{"get":{"tags":["papers"],"summary":"Get Conference Papers","description":"Get papers from a specific conference.\n\nArgs:\n    conference_id: Conference ID (e.g., \"neurips2024\")\n    track: Optional track filter (oral, poster, spotlight)\n    category: Optional category/area filter\n    limit: Maximum results to return\n    offset: Number of results to skip (pagination)\n\nReturns:\n    {\n        \"conference_id\": \"neurips2024\",\n        \"count\": 42,\n        \"total\": 4035,\n        \"papers\": [...]\n    }","operationId":"get_conference_papers_papers_conference__conference_id__get","parameters":[{"name":"conference_id","in":"path","required":true,"schema":{"type":"string","title":"Conference Id"}},{"name":"track","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by track (oral, poster, spotlight)","title":"Track"},"description":"Filter by track (oral, poster, spotlight)"},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by category/area (paper_conferences.category)","title":"Category"},"description":"Filter by category/area (paper_conferences.category)"},{"name":"category_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by taxonomy category ID (paper_categories)","title":"Category Id"},"description":"Filter by taxonomy category ID (paper_categories)"},{"name":"has_code","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter papers that have linked repos","title":"Has Code"},"description":"Filter papers that have linked repos"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"description":"Maximum number of results","default":100,"title":"Limit"},"description":"Maximum number of results"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Number of results to skip","default":0,"title":"Offset"},"description":"Number of results to skip"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Conference Papers Papers Conference  Conference Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/{paper_id}/repos":{"get":{"tags":["papers"],"summary":"Get Paper Repos","description":"Get cached repositories for a paper.\n\nReturns repositories that have been linked to this paper during caching,\nalong with their scores and metadata.\n\nArgs:\n    paper_id: Paper ID (arXiv ID like \"2301.12345\")\n    limit: Maximum number of repos to return\n\nReturns:\n    {\n        \"paper\": {\n            \"id\": \"2301.12345\",\n            \"title\": \"...\",\n            ...\n        },\n        \"top_repos\": [\n            {\n                \"full_name\": \"author/repo\",\n                \"html_url\": \"https://github.com/...\",\n                \"description\": \"...\",\n                \"stars\": 1234,\n                \"forks\": 56,\n                \"score\": 0.92,\n                \"is_official\": true,\n                \"metadata_scores\": {...},\n                \"readme_summary\": \"...\",\n                \"languages\": {...},\n                \"topics\": [...]\n            }\n        ],\n        \"source\": \"cache\"\n    }","operationId":"get_paper_repos_papers__paper_id__repos_get","parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Maximum number of repos","default":10,"title":"Limit"},"description":"Maximum number of repos"},{"name":"include_possible","in":"query","required":false,"schema":{"type":"boolean","description":"When true (default), include 'possible_match' tier repos alongside 'official' and 'high_confidence_community'. Set to false to only return confident matches.","default":true,"title":"Include Possible"},"description":"When true (default), include 'possible_match' tier repos alongside 'official' and 'high_confidence_community'. Set to false to only return confident matches."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Paper Repos Papers  Paper Id  Repos Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/{paper_id}/fork-graph":{"get":{"tags":["papers"],"summary":"Get Paper Fork Graph","description":"Fork-graph for a paper's confident implementations.\n\nFor each `official` / `high_confidence_community` repo attached to the\npaper, returns aggregate fork counts plus the top-N notable forks (active,\nsorted by stars). Backed by the `repository_forks` table populated by the\n2026-04 backfill (1.5M edges across 89k distinct parents).\n\nArgs:\n    paper_id: Paper ID (arXiv ID, S2 hash, or `or_<id>`).\n    parent_limit: Cap on how many parent repos to walk.\n    forks_per_parent: Cap on notable forks returned per parent.\n\nReturns:\n    {\n        \"paper_id\": \"2309.06180\",\n        \"repos\": [\n            {\n                \"full_name\": \"vllm-project/vllm\",\n                \"html_url\": \"https://github.com/vllm-project/vllm\",\n                \"tier\": \"official\",\n                \"stars\": 53000,\n                \"total_forks\": 394,\n                \"active_forks\": 380,\n                \"notable_forks\": [\n                    {\n                        \"full_name\": \"SystemPanic/vllm-windows\",\n                        \"html_url\": \"https://github.com/SystemPanic/vllm-windows\",\n                        \"stars\": 452,\n                        \"pushed_at\": \"2026-05-04T07:33:50+00:00\",\n                        \"is_archived\": false\n                    }\n                ]\n            }\n        ],\n        \"source\": \"cache\"\n    }","operationId":"get_paper_fork_graph_papers__paper_id__fork_graph_get","parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}},{"name":"parent_limit","in":"query","required":false,"schema":{"type":"integer","maximum":10,"minimum":1,"description":"Max number of parent repos to surface","default":3,"title":"Parent Limit"},"description":"Max number of parent repos to surface"},{"name":"forks_per_parent","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"description":"Max notable forks per parent repo","default":5,"title":"Forks Per Parent"},"description":"Max notable forks per parent repo"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Paper Fork Graph Papers  Paper Id  Fork Graph Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/{paper_id}":{"get":{"tags":["papers"],"summary":"Get Paper Details","description":"Get detailed paper information from cache.\n\nSupports both ArXiv IDs and OpenReview IDs (with 'or_' prefix).\n\nArgs:\n    paper_id: Paper ID (e.g., \"2301.12345\" or \"or_iEeiZlTbts\")\n\nReturns:\n    {\n        \"id\": \"2301.12345\",\n        \"title\": \"...\",\n        \"summary\": \"...\",\n        \"authors\": [\"...\"],\n        \"published_date\": \"2023-01-25T00:00:00\",\n        \"categories\": [\"cs.AI\"],\n        \"source\": \"arxiv\",\n        \"url\": \"https://arxiv.org/abs/2301.12345\",\n        \"official_code_links\": [\"https://github.com/...\"],\n        \"conferences\": [...]  # If paper is in conferences\n    }","operationId":"get_paper_details_papers__paper_id__get","parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Paper Details Papers  Paper Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/{paper_id}/similar":{"get":{"tags":["papers"],"summary":"Get Similar Papers","description":"Find papers similar to the given paper using embedding cosine similarity.\n\nUses pre-computed paper embeddings stored in the database.\nReturns papers sorted by similarity score.","operationId":"get_similar_papers_papers__paper_id__similar_get","parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"description":"Number of similar papers to return","default":6,"title":"Limit"},"description":"Number of similar papers to return"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/{paper_id}/request-refresh":{"post":{"tags":["papers"],"summary":"Request Paper Refresh","description":"User-initiated request to refresh code search for a paper.","operationId":"request_paper_refresh_papers__paper_id__request_refresh_post","parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/papers/{paper_id}/refresh-status":{"get":{"tags":["papers"],"summary":"Get Refresh Status","description":"Get the refresh request status for a paper.","operationId":"get_refresh_status_papers__paper_id__refresh_status_get","parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conferences":{"get":{"tags":["conferences"],"summary":"List Conferences","description":"Get list of all cached conferences with statistics.\n\nReturns:\n    [\n        {\n            \"id\": \"neurips2024\",\n            \"name\": \"NeurIPS\",\n            \"full_name\": \"Conference on Neural Information Processing Systems\",\n            \"year\": 2024,\n            \"series\": \"neurips\",\n            \"url\": \"https://neurips.cc/Conferences/2024\",\n            \"total_papers\": 4035,\n            \"cached_papers\": 4035,\n            \"papers_with_code\": 1250,\n            \"cached_at\": \"2025-12-10T...\",\n            \"last_updated\": \"2025-12-10T...\"\n        },\n        ...\n    ]","operationId":"list_conferences_conferences_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Response List Conferences Conferences Get"}}}}}}},"/conferences/recent-code-drops":{"get":{"tags":["conferences"],"summary":"Recent Code Drops","description":"Papers from conferences whose repos had recent commits.\nReturns the most interesting recent code activity across all conferences.\nFilters for repos with >=10 stars or official status to reduce noise.","operationId":"recent_code_drops_conferences_recent_code_drops_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":20,"minimum":1,"default":8,"title":"Limit"}},{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":180,"minimum":7,"default":30,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Recent Code Drops Conferences Recent Code Drops Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/conferences/stats":{"get":{"tags":["conferences"],"summary":"Get Conference Stats","description":"Get overall conference statistics.\n\nReturns:\n    {\n        \"total_conferences\": 3,\n        \"total_papers\": 12000,\n        \"total_with_code\": 3500,\n        \"by_series\": {...},\n        \"by_year\": {...}\n    }","operationId":"get_conference_stats_conferences_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Conference Stats Conferences Stats Get"}}}}}}},"/conferences/{conference_id}":{"get":{"tags":["conferences"],"summary":"Get Conference Details","description":"Get detailed information about a specific conference.","operationId":"get_conference_details_conferences__conference_id__get","parameters":[{"name":"conference_id","in":"path","required":true,"schema":{"type":"string","title":"Conference Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Conference Details Conferences  Conference Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/categories/":{"get":{"tags":["categories"],"summary":"List Categories","description":"List all category areas with their subcategories and paper counts.\n\nReturns categories grouped by area (cv, nlp, mm, etc.) with\ntotal paper counts for each area and subcategory.","operationId":"list_categories_categories__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/categories/flat":{"get":{"tags":["categories"],"summary":"List Categories Flat","description":"List all categories as a flat list (useful for dropdowns/filters).","operationId":"list_categories_flat_categories_flat_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/categories/filters/years":{"get":{"tags":["categories"],"summary":"Get Paper Years","description":"Get list of available publication years for filtering.\n\nReturns years in descending order with paper counts.","operationId":"get_paper_years_categories_filters_years_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/categories/{category_id}":{"get":{"tags":["categories"],"summary":"Get Category","description":"Get details for a single category.","operationId":"get_category_categories__category_id__get","parameters":[{"name":"category_id","in":"path","required":true,"schema":{"type":"string","title":"Category Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/categories/{category_id}/papers":{"get":{"tags":["categories"],"summary":"Get Category Papers","description":"Get papers in a specific category with optional filters.\n\nPapers are ordered by classification confidence and publication date.\n\nArgs:\n    arxiv_category: Filter by arXiv category (e.g., cs.CV for Computer Vision papers).\n                   Papers store their arXiv categories in a JSON array, this filters\n                   papers that have the specified category in their list.","operationId":"get_category_papers_categories__category_id__papers_get","parameters":[{"name":"category_id","in":"path","required":true,"schema":{"type":"string","title":"Category Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"primary_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only return papers where this is the primary category","default":false,"title":"Primary Only"},"description":"Only return papers where this is the primary category"},{"name":"conference_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by conference ID","title":"Conference Id"},"description":"Filter by conference ID"},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filter by publication year","title":"Year"},"description":"Filter by publication year"},{"name":"arxiv_category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by arXiv category (e.g., cs.CV, cs.LG, cs.CL)","title":"Arxiv Category"},"description":"Filter by arXiv category (e.g., cs.CV, cs.LG, cs.CL)"},{"name":"has_code","in":"query","required":false,"schema":{"type":"boolean","description":"Only return papers with linked code repositories","default":false,"title":"Has Code"},"description":"Only return papers with linked code repositories"},{"name":"official_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only return papers with official/verified code repos","default":false,"title":"Official Only"},"description":"Only return papers with official/verified code repos"},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["relevant","recent","trending"],"type":"string","description":"Sort order: relevant (default), recent, or trending","default":"relevant","title":"Sort By"},"description":"Sort order: relevant (default), recent, or trending"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/categories/area/{area_id}":{"get":{"tags":["categories"],"summary":"Get Area Categories","description":"Get all categories within a specific area.","operationId":"get_area_categories_categories_area__area_id__get","parameters":[{"name":"area_id","in":"path","required":true,"schema":{"type":"string","title":"Area Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/categories/area/{area_id}/papers":{"get":{"tags":["categories"],"summary":"Get Area Papers","description":"Get all papers within an area (across all categories in that area).\n\nPapers are ordered by publication date (newest first).\nSupports filtering by conference, year, arxiv_category, has_code, and official_only.","operationId":"get_area_papers_categories_area__area_id__papers_get","parameters":[{"name":"area_id","in":"path","required":true,"schema":{"type":"string","title":"Area Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"conference_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by conference","title":"Conference Id"},"description":"Filter by conference"},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filter by publication year","title":"Year"},"description":"Filter by publication year"},{"name":"arxiv_category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by arXiv category (e.g., cs.CV, cs.LG, cs.CL)","title":"Arxiv Category"},"description":"Filter by arXiv category (e.g., cs.CV, cs.LG, cs.CL)"},{"name":"has_code","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter papers that have code","title":"Has Code"},"description":"Filter papers that have code"},{"name":"official_only","in":"query","required":false,"schema":{"type":"boolean","description":"Only return papers with official/verified code repos","default":false,"title":"Official Only"},"description":"Only return papers with official/verified code repos"},{"name":"sort_by","in":"query","required":false,"schema":{"enum":["relevant","recent","trending"],"type":"string","description":"Sort order: relevant (default), recent, or trending","default":"relevant","title":"Sort By"},"description":"Sort order: relevant (default), recent, or trending"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/categories/filters/arxiv-categories":{"get":{"tags":["categories"],"summary":"Get Arxiv Categories","description":"Get list of arXiv categories present in the database with paper counts.\n\nUseful for building filter UIs that show available arXiv categories.\nReturns categories ordered by paper count (most common first).","operationId":"get_arxiv_categories_categories_filters_arxiv_categories_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/categories/filters/arxiv-categories/by-area":{"get":{"tags":["categories"],"summary":"Get Arxiv Categories By Area","description":"Get recommended arXiv categories for each category area.\n\nReturns the arXiv category mappings from the taxonomy config.\nUseful for understanding which arXiv categories to cache for complete coverage.","operationId":"get_arxiv_categories_by_area_categories_filters_arxiv_categories_by_area_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/trending/":{"get":{"tags":["trending"],"summary":"Get Trending Papers","description":"Get trending/interesting papers from our database.\n\nComputes a trending score based on repository stars, repo count,\nrecency, official code availability, and HuggingFace trending boost.\n\nSort modes:\n- hot: Balanced trending score (default — best for homepage)\n- new: Most recently published papers with code\n- fresh: Papers that just got code discovered (latest search_date)\n- discussed: Community buzz — HF upvotes + repo implementations","operationId":"get_trending_papers_trending__get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":50,"minimum":1,"description":"Maximum number of papers","default":20,"title":"Limit"},"description":"Maximum number of papers"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"description":"Offset for pagination","default":0,"title":"Offset"},"description":"Offset for pagination"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"Sort mode: hot, new, fresh, discussed","default":"hot","title":"Sort"},"description":"Sort mode: hot, new, fresh, discussed"},{"name":"has_code","in":"query","required":false,"schema":{"type":"boolean","description":"Only show papers with code repos","default":true,"title":"Has Code"},"description":"Only show papers with code repos"},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by arXiv category","title":"Category"},"description":"Filter by arXiv category"},{"name":"conference","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by conference ID","title":"Conference"},"description":"Filter by conference ID"},{"name":"days","in":"query","required":false,"schema":{"anyOf":[{"type":"integer","maximum":365,"minimum":1},{"type":"null"}],"description":"Limit to papers from last N days","title":"Days"},"description":"Limit to papers from last N days"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Trending Papers Trending  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/trending/stats":{"get":{"tags":["trending"],"summary":"Get Trending Stats","description":"Get statistics about trending data collection.","operationId":"get_trending_stats_trending_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Trending Stats Trending Stats Get"}}}}}}},"/trending/activity":{"get":{"tags":["trending"],"summary":"Get Platform Activity","description":"Live activity pulse — aggregated platform stats for the last 7 days.\nReturns counts of new papers, new repos, recent commits, etc.\nCached for 5 minutes on the client side.","operationId":"get_platform_activity_trending_activity_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/comments/paper/{paper_id}":{"get":{"tags":["comments"],"summary":"Get Paper Comments","description":"Get comments for a paper.\n\nReturns top-level comments with reply counts.\nReplies can be fetched separately.","operationId":"get_paper_comments_comments_paper__paper_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Paper Comments Comments Paper  Paper Id  Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["comments"],"summary":"Create Comment","description":"Create a new comment on a paper.\n\nRequires authentication.","operationId":"create_comment_comments_paper__paper_id__post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentCreate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Create Comment Comments Paper  Paper Id  Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/comments/{comment_id}/replies":{"get":{"tags":["comments"],"summary":"Get Comment Replies","description":"Get replies to a specific comment.","operationId":"get_comment_replies_comments__comment_id__replies_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"comment_id","in":"path","required":true,"schema":{"type":"string","title":"Comment Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Comment Replies Comments  Comment Id  Replies Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/comments/{comment_id}":{"put":{"tags":["comments"],"summary":"Update Comment","description":"Update a comment. Only the author can update.","operationId":"update_comment_comments__comment_id__put","security":[{"HTTPBearer":[]}],"parameters":[{"name":"comment_id","in":"path","required":true,"schema":{"type":"string","title":"Comment Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommentUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Update Comment Comments  Comment Id  Put"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["comments"],"summary":"Delete Comment","description":"Soft-delete a comment. Only the author can delete.\n\nComments with replies are soft-deleted (content hidden).\nComments without replies are hard-deleted.","operationId":"delete_comment_comments__comment_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"comment_id","in":"path","required":true,"schema":{"type":"string","title":"Comment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":{"type":"string"},"title":"Response Delete Comment Comments  Comment Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/comments/{comment_id}/upvote":{"post":{"tags":["comments"],"summary":"Toggle Upvote","description":"Toggle upvote on a comment.\n\nIf already upvoted, removes the upvote.","operationId":"toggle_upvote_comments__comment_id__upvote_post","security":[{"HTTPBearer":[]}],"parameters":[{"name":"comment_id","in":"path","required":true,"schema":{"type":"string","title":"Comment Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Toggle Upvote Comments  Comment Id  Upvote Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cache/stats":{"get":{"tags":["cache"],"summary":"Get Cache Stats","description":"Get comprehensive cache statistics.\n\n**Admin only endpoint.**\n\nReturns:\n    - Total counts for papers, repositories, embeddings, links\n    - FAISS index status\n    - Recent activity metrics\n    - Storage usage estimates","operationId":"get_cache_stats_api_cache_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Cache Stats Api Cache Stats Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/cache/stats/file-cache":{"get":{"tags":["cache"],"summary":"Get File Cache Stats","description":"Get statistics from the file cache (~/codeofpaper_data/cache/).\n\n**Admin only endpoint.**\n\nReturns:\n    - Total papers in file cache\n    - Cache size in MB\n    - Date range coverage\n    - Categories found\n    - Average papers per day","operationId":"get_file_cache_stats_api_cache_stats_file_cache_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get File Cache Stats Api Cache Stats File Cache Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/cache/checkpoints":{"get":{"tags":["cache"],"summary":"Get Checkpoints","description":"Get cache flow checkpoints with optional filtering.\n\n**Admin only endpoint.**\n\nArgs:\n    flow_type: Filter by flow type (paper_caching, embedding_generation, repository_search)\n    status: Filter by status (running, paused, completed, failed)\n    limit: Maximum number of checkpoints to return\n\nReturns:\n    List of checkpoints with progress and status information","operationId":"get_checkpoints_api_cache_checkpoints_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"flow_type","in":"query","required":false,"schema":{"type":"string","title":"Flow Type"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Get Checkpoints Api Cache Checkpoints Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cache/checkpoints/{checkpoint_id}/logs":{"get":{"tags":["cache"],"summary":"Get Checkpoint Logs","description":"Get logs for a specific checkpoint.\n\nArgs:\n    checkpoint_id: UUID of the checkpoint\n    level: Filter by log level (INFO, WARNING, ERROR)\n    limit: Maximum number of log entries to return\n\nReturns:\n    List of log entries for the checkpoint","operationId":"get_checkpoint_logs_api_cache_checkpoints__checkpoint_id__logs_get","parameters":[{"name":"checkpoint_id","in":"path","required":true,"schema":{"type":"string","title":"Checkpoint Id"}},{"name":"level","in":"query","required":false,"schema":{"type":"string","title":"Level"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","additionalProperties":true},"title":"Response Get Checkpoint Logs Api Cache Checkpoints  Checkpoint Id  Logs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/cache/flows/status":{"get":{"tags":["cache"],"summary":"Get Flows Status","description":"Get current status of all cache flows.\n\n**Admin only endpoint.**\n\nReturns:\n    Status summary for each flow type including running jobs","operationId":"get_flows_status_api_cache_flows_status_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Flows Status Api Cache Flows Status Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/cache/health":{"get":{"tags":["cache"],"summary":"Get Cache Health","description":"Health check for cache system.\n\nReturns:\n    Health status including database connectivity and service availability","operationId":"get_cache_health_api_cache_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Cache Health Api Cache Health Get"}}}}}}},"/cache/stats":{"get":{"tags":["cache-admin"],"summary":"Get Cache Statistics","description":"Get comprehensive cache statistics.\n\nReturns total counts, breakdowns by year/category/model, and cache size.","operationId":"get_cache_statistics_cache_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}},"security":[{"HTTPBearer":[]}]}},"/cache/papers/search":{"get":{"tags":["cache-admin"],"summary":"Search Papers","description":"Search cached papers with flexible filters and pagination.\n\nSupports filtering by date range, category, presence of embeddings/repos/summaries,\nand specific models. Returns paginated results with total count.\nDeduplicates by canonical paper ID unless ?show_duplicates=true.","operationId":"search_papers_cache_papers_search_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"query","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search in paper titles","title":"Query"},"description":"Search in paper titles"},{"name":"year","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Filter by year","title":"Year"},"description":"Filter by year"},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by category (e.g., cs.LG)","title":"Category"},"description":"Filter by category (e.g., cs.LG)"},{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter from date (YYYY-MM-DD)","title":"Date From"},"description":"Filter from date (YYYY-MM-DD)"},{"name":"date_to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter to date (YYYY-MM-DD)","title":"Date To"},"description":"Filter to date (YYYY-MM-DD)"},{"name":"has_embeddings","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter by embedding presence","title":"Has Embeddings"},"description":"Filter by embedding presence"},{"name":"has_repos","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter by repository presence","title":"Has Repos"},"description":"Filter by repository presence"},{"name":"has_summaries","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Filter by summary presence","title":"Has Summaries"},"description":"Filter by summary presence"},{"name":"embedding_model","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by embedding model","title":"Embedding Model"},"description":"Filter by embedding model"},{"name":"summary_model","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by summary model","title":"Summary Model"},"description":"Filter by summary model"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Items per page","default":50,"title":"Page Size"},"description":"Items per page"},{"name":"sort_by","in":"query","required":false,"schema":{"type":"string","description":"Sort field","default":"published_date","title":"Sort By"},"description":"Sort field"},{"name":"sort_order","in":"query","required":false,"schema":{"type":"string","pattern":"^(asc|desc)$","description":"Sort order","default":"desc","title":"Sort Order"},"description":"Sort order"},{"name":"show_duplicates","in":"query","required":false,"schema":{"type":"boolean","description":"Show all duplicate IDs (default: dedup by canonical ID)","default":false,"title":"Show Duplicates"},"description":"Show all duplicate IDs (default: dedup by canonical ID)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/cache/papers/{paper_id}":{"get":{"tags":["cache-admin"],"summary":"Get Paper Detail","description":"Get detailed information about a specific paper.\n\nIncludes paper metadata, cache status, repositories, summaries, and storage sizes.","operationId":"get_paper_detail_cache_papers__paper_id__get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"paper_id","in":"path","required":true,"schema":{"type":"string","title":"Paper Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/cache/repositories/search":{"get":{"tags":["cache-admin"],"summary":"Search Repositories","description":"Search cached repositories with filters and pagination.\n\nReturns repositories sorted by stars (highest first).","operationId":"search_repositories_cache_repositories_search_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"query","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Search in repository names/descriptions","title":"Query"},"description":"Search in repository names/descriptions"},{"name":"min_stars","in":"query","required":false,"schema":{"anyOf":[{"type":"integer"},{"type":"null"}],"description":"Minimum stars","title":"Min Stars"},"description":"Minimum stars"},{"name":"language","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter by language","title":"Language"},"description":"Filter by language"},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Page number","default":1,"title":"Page"},"description":"Page number"},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Items per page","default":50,"title":"Page Size"},"description":"Items per page"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/cache/sessions":{"get":{"tags":["cache-admin"],"summary":"List Sessions","description":"List caching sessions with optional filters.\n\nReturns sessions sorted by date (newest first).","operationId":"list_sessions_cache_sessions_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string","pattern":"^(running|completed|failed)$"},{"type":"null"}],"description":"Filter by status","title":"Status"},"description":"Filter by status"},{"name":"date_from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Filter from date (YYYY-MM-DD)","title":"Date From"},"description":"Filter from date (YYYY-MM-DD)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"description":"Maximum number of sessions","default":50,"title":"Limit"},"description":"Maximum number of sessions"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/ops-summary":{"get":{"tags":["admin"],"summary":"Get Ops Summary","description":"Aggregated operational overview for the admin landing page.\n\nReturns system health, data freshness, quick totals, and cache-vs-DB delta.","operationId":"get_ops_summary_api_admin_ops_summary_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Ops Summary Api Admin Ops Summary Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/coverage/rebuild-index":{"post":{"tags":["admin"],"summary":"Rebuild Coverage Index","description":"Scan cache directory and build a coverage index file.\nThis avoids scanning 141k+ files on every dashboard load.","operationId":"rebuild_coverage_index_api_admin_coverage_rebuild_index_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Rebuild Coverage Index Api Admin Coverage Rebuild Index Post"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/coverage":{"get":{"tags":["admin"],"summary":"Get Coverage Matrix","description":"Coverage matrix: cache files vs DB, per category per month.\nReads the pre-built cache index and enriches with DB counts.","operationId":"get_coverage_matrix_api_admin_coverage_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Coverage Matrix Api Admin Coverage Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/conferences/gaps":{"get":{"tags":["admin"],"summary":"Get Conference Gaps","description":"Gap analysis for each conference: cache files vs DB vs expected total.","operationId":"get_conference_gaps_api_admin_conferences_gaps_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Conference Gaps Api Admin Conferences Gaps Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/users/analytics":{"get":{"tags":["admin"],"summary":"Get User Analytics","description":"User signup trends, activity stats, and top users.","operationId":"get_user_analytics_api_admin_users_analytics_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get User Analytics Api Admin Users Analytics Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/database/health":{"get":{"tags":["admin"],"summary":"Get Database Health","description":"PostgreSQL internals: table sizes, index stats, connection pool, maintenance.","operationId":"get_database_health_api_admin_database_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Database Health Api Admin Database Health Get"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/search-analytics":{"get":{"tags":["admin"],"summary":"Get Search Analytics","description":"Search query analytics: recent queries, top queries, zero-result queries,\nand volume over time.","operationId":"get_search_analytics_api_admin_search_analytics_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":7,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Search Analytics Api Admin Search Analytics Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/api-logs":{"get":{"tags":["admin"],"summary":"Get Api Logs","description":"API request traffic analytics: volume, top endpoints, errors, latency.","operationId":"get_api_logs_api_admin_api_logs_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":7,"title":"Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Get Api Logs Api Admin Api Logs Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/api-logs/cleanup":{"delete":{"tags":["admin"],"summary":"Cleanup Old Logs","description":"Delete api_request_logs and search_queries older than retention_days.","operationId":"cleanup_old_logs_api_admin_api_logs_cleanup_delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"retention_days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":7,"default":30,"title":"Retention Days"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Cleanup Old Logs Api Admin Api Logs Cleanup Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/costs":{"get":{"tags":["admin"],"summary":"Get Costs","description":"Cost tracking: manual entries + configuration summary.","operationId":"get_costs_api_admin_costs_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Get Costs Api Admin Costs Get"}}}}},"security":[{"HTTPBearer":[]}]},"post":{"tags":["admin"],"summary":"Add Cost Entry","description":"Add a manual cost entry.","operationId":"add_cost_entry_api_admin_costs_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Add Cost Entry Api Admin Costs Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/costs/{entry_id}":{"delete":{"tags":["admin"],"summary":"Delete Cost Entry","description":"Delete a cost entry by ID.","operationId":"delete_cost_entry_api_admin_costs__entry_id__delete","security":[{"HTTPBearer":[]}],"parameters":[{"name":"entry_id","in":"path","required":true,"schema":{"type":"string","title":"Entry Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Delete Cost Entry Api Admin Costs  Entry Id  Delete"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/admin/reprocess":{"post":{"tags":["admin"],"summary":"Admin Reprocess Papers","description":"Admin: queue papers for reprocessing. Body: {\"paper_ids\": [\"2512.10942\", ...]}","operationId":"admin_reprocess_papers_api_admin_reprocess_post","requestBody":{"content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Body"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"additionalProperties":true,"type":"object","title":"Response Admin Reprocess Papers Api Admin Reprocess Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"security":[{"HTTPBearer":[]}]}},"/api/admin/reprocess-queue":{"get":{"tags":["admin"],"summary":"Admin Get Reprocess Queue","description":"Admin: view reprocess queue entries with computed scores.","operationId":"admin_get_reprocess_queue_api_admin_reprocess_queue_get","security":[{"HTTPBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","default":"pending","title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{},"title":"Response Admin Get Reprocess Queue Api Admin Reprocess Queue Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/repos/{owner}/{name}/health":{"get":{"tags":["repos"],"summary":"Get Repo Health","description":"Return the cached liveness state of a repo by `owner/name`.\n\nThis is intentionally a DB-only lookup, not a live HEAD against GitHub,\nso it stays cheap to call from the frontend on every paper page render.\nThe nightly `repo_health_sweep` job is what flips the underlying state.\n\nResponse shape:\n    {\n      \"full_name\": \"owner/name\",\n      \"alive\": bool,\n      \"stale\": bool,           # true when last_verified_at is missing or > 14d\n      \"http_status\": int|null,\n      \"last_verified_at\": iso|null\n    }\n\nReturns 404 only when we have never heard of the repo at all (so the\nfrontend can't use this endpoint to enumerate our DB).","operationId":"get_repo_health_repos__owner___name__health_get","parameters":[{"name":"owner","in":"path","required":true,"schema":{"type":"string","title":"Owner"}},{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/health":{"get":{"summary":"Health","description":"Health check endpoint with database status.","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"BatchVoteRequest":{"properties":{"paper_id":{"type":"string","title":"Paper Id"},"repo_full_name":{"type":"string","title":"Repo Full Name"}},"type":"object","required":["paper_id","repo_full_name"],"title":"BatchVoteRequest"},"BatchVoteResponse":{"properties":{"votes":{"additionalProperties":{"$ref":"#/components/schemas/VoteResponse"},"type":"object","title":"Votes"}},"type":"object","required":["votes"],"title":"BatchVoteResponse"},"CommentCreate":{"properties":{"content":{"type":"string","maxLength":10000,"minLength":1,"title":"Content"},"parent_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Parent Id"}},"type":"object","required":["content"],"title":"CommentCreate","description":"Request body for creating a comment."},"CommentUpdate":{"properties":{"content":{"type":"string","maxLength":10000,"minLength":1,"title":"Content"}},"type":"object","required":["content"],"title":"CommentUpdate","description":"Request body for updating a comment."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"TokenResponse":{"properties":{"access_token":{"type":"string","title":"Access Token"},"refresh_token":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Refresh Token"},"token_type":{"type":"string","title":"Token Type","default":"bearer"},"expires_in":{"type":"integer","title":"Expires In"}},"type":"object","required":["access_token","expires_in"],"title":"TokenResponse","description":"Response model for token generation."},"UserResponse":{"properties":{"id":{"type":"string","title":"Id"},"github_id":{"type":"integer","title":"Github Id"},"github_username":{"type":"string","title":"Github Username"},"display_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Display Name"},"github_avatar_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Github Avatar Url"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"user_type":{"type":"string","title":"User Type"},"is_verified_author":{"type":"boolean","title":"Is Verified Author"},"reputation_points":{"type":"integer","title":"Reputation Points"},"contribution_count":{"type":"integer","title":"Contribution Count"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"last_login_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Login At"}},"type":"object","required":["id","github_id","github_username","user_type","is_verified_author","reputation_points","contribution_count","created_at"],"title":"UserResponse","description":"Response model for user information."},"UserUpdateRequest":{"properties":{"display_name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Display Name"},"bio":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bio"},"email_notifications":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Email Notifications"},"notification_frequency":{"anyOf":[{"type":"string","pattern":"^(instant|daily|weekly|never)$"},{"type":"null"}],"title":"Notification Frequency"}},"type":"object","title":"UserUpdateRequest","description":"Request model for updating user profile."},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VoteRequest":{"properties":{"vote_type":{"type":"string","title":"Vote Type"}},"type":"object","required":["vote_type"],"title":"VoteRequest"},"VoteResponse":{"properties":{"upvotes":{"type":"integer","title":"Upvotes"},"downvotes":{"type":"integer","title":"Downvotes"},"user_vote":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"User Vote"}},"type":"object","required":["upvotes","downvotes","user_vote"],"title":"VoteResponse"}},"securitySchemes":{"HTTPBearer":{"type":"http","scheme":"bearer"}}}}