{"openapi":"3.1.0","info":{"title":"DOL Analytics API","description":"DOL Analytics API for PERM data visualization and predictions","version":"0.1.0"},"paths":{"/api/data/clear-cache":{"post":{"tags":["data"],"summary":"Clear Dashboard Cache","description":"Clear the dashboard cache manually.\nUseful during development or when fresh data is needed immediately.","operationId":"clear_dashboard_cache_api_data_clear_cache_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/data/admin/rate-limit-stats":{"get":{"tags":["data"],"summary":"Get Rate Limit Stats","description":"Get rate limiting statistics for monitoring.\nShows suspicious IPs and current rate limit status.","operationId":"get_rate_limit_stats_api_data_admin_rate_limit_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/data/admin/block-ip":{"post":{"tags":["data"],"summary":"Block Ip","description":"Manually block an IP address.\nDuration is in seconds (default: 1 hour).","operationId":"block_ip_api_data_admin_block_ip_post","parameters":[{"name":"ip_address","in":"query","required":true,"schema":{"type":"string","title":"Ip Address"}},{"name":"duration","in":"query","required":false,"schema":{"type":"integer","default":3600,"title":"Duration"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/data/company-search":{"post":{"tags":["data"],"summary":"Search Companies","description":"Search for company names in perm_cases table for autocomplete.\nSearches data from March 1st, 2024 onward. Protected by reCAPTCHA to prevent scraping.","operationId":"search_companies_api_data_company_search_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySearchRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanySearchResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/data/company-cases":{"post":{"tags":["data"],"summary":"Get Company Cases","description":"Get PERM cases for a specific company within a date range.\nProtected by reCAPTCHA to prevent scraping.\nReturns case number, job title, priority date, and other relevant information.\nDate range limited to March 1st, 2024 through today with maximum 2-week window.","operationId":"get_company_cases_api_data_company_cases_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyCasesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompanyCasesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/data/updated-cases":{"post":{"tags":["data"],"summary":"Get Updated Cases","description":"Get PERM cases that were updated on a specific date (ET timezone).\nReturns case number, job title, current status, previous status, update timestamp, and other relevant information.\nDate range is limited to March 1st, 2024 through today.\nExcludes withdrawn cases from results. No rate limiting or reCAPTCHA protection.","operationId":"get_updated_cases_api_data_updated_cases_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatedCasesRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatedCasesResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/data/dashboard":{"get":{"tags":["data"],"summary":"Get Dashboard Data","description":"Get dashboard visualization data in the format expected by the frontend.\nUses caching for common time periods (7, 30, 90, 180 days).\n\nParameters:\n- days: Number of days to include in data (1-365)\n- data_type: Type of data to fetch - 'certified' (uses certified_total column) or 'processed' (uses processed_total column)","operationId":"get_dashboard_data_api_data_dashboard_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to include in data","default":30,"title":"Days"},"description":"Number of days to include in data"},{"name":"data_type","in":"query","required":false,"schema":{"type":"string","pattern":"^(certified|processed)$","description":"Type of data to fetch: 'certified' or 'processed'","default":"certified","title":"Data Type"},"description":"Type of data to fetch: 'certified' or 'processed'"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/data/daily-volume":{"get":{"tags":["data"],"summary":"Get Daily Volume","description":"Get daily volume data for a specific date range.","operationId":"get_daily_volume_api_data_daily_volume_get","parameters":[{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Start date (defaults to 30 days ago)","title":"Start Date"},"description":"Start date (defaults to 30 days ago)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"End date (defaults to today)","title":"End Date"},"description":"End date (defaults to today)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/data/weekly-averages":{"get":{"tags":["data"],"summary":"Get Weekly Averages","description":"Get average volume by day of week.","operationId":"get_weekly_averages_api_data_weekly_averages_get","parameters":[{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Start date (defaults to 30 days ago)","title":"Start Date"},"description":"Start date (defaults to 30 days ago)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"End date (defaults to today)","title":"End Date"},"description":"End date (defaults to today)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/data/weekly-volumes":{"get":{"tags":["data"],"summary":"Get Weekly Volumes","description":"Get weekly volume totals.","operationId":"get_weekly_volumes_api_data_weekly_volumes_get","parameters":[{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Start date (defaults to 30 days ago)","title":"Start Date"},"description":"Start date (defaults to 30 days ago)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"End date (defaults to today)","title":"End Date"},"description":"End date (defaults to today)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/data/monthly-volumes":{"get":{"tags":["data"],"summary":"Get Monthly Volumes","description":"Get monthly volume data.","operationId":"get_monthly_volumes_api_data_monthly_volumes_get","parameters":[{"name":"start_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"Start date (defaults to 30 days ago)","title":"Start Date"},"description":"Start date (defaults to 30 days ago)"},{"name":"end_date","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date"},{"type":"null"}],"description":"End date (defaults to today)","title":"End Date"},"description":"End date (defaults to today)"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/data/todays-progress":{"get":{"tags":["data"],"summary":"Get Todays Progress","description":"Get today's progress metrics.","operationId":"get_todays_progress_api_data_todays_progress_get","parameters":[{"name":"days","in":"query","required":false,"schema":{"type":"integer","maximum":365,"minimum":1,"description":"Number of days to compare against","default":1,"title":"Days"},"description":"Number of days to compare against"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/data/monthly-backlog":{"get":{"tags":["data"],"summary":"Get Monthly Backlog","description":"Get monthly backlog data showing backlog (ANALYST REVIEW + RECONSIDERATION APPEALS), WITHDRAWN, DENIED, and RFI cases.","operationId":"get_monthly_backlog_api_data_monthly_backlog_get","parameters":[{"name":"months","in":"query","required":false,"schema":{"type":"integer","maximum":36,"minimum":1,"description":"Number of months to include","default":12,"title":"Months"},"description":"Number of months to include"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/data/processing-times":{"get":{"tags":["data"],"summary":"Get Processing Times","description":"Get latest processing time estimates.","operationId":"get_processing_times_api_data_processing_times_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/data/perm-cases":{"get":{"tags":["data"],"summary":"Get Perm Cases","description":"Get PERM cases activity data for debugging and testing.","operationId":"get_perm_cases_api_data_perm_cases_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/api/predictions/from-date":{"post":{"tags":["predictions"],"summary":"Predict From Submit Date","description":"Predict completion date for a case submitted on a specific date,\nfactoring in current processing rates, queue position, and employer name.","operationId":"predict_from_submit_date_api_predictions_from_date_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DateSubmissionRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/predictions/requests":{"get":{"tags":["predictions"],"summary":"Get Prediction Requests","description":"Get stored prediction requests with pagination.","operationId":"get_prediction_requests_api_predictions_requests_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/predictions/requests/{request_id}":{"get":{"tags":["predictions"],"summary":"Get Prediction Request","description":"Get a specific prediction request by ID.","operationId":"get_prediction_request_api_predictions_requests__request_id__get","parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"integer","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/chatbot/":{"post":{"tags":["chatbot"],"summary":"Chatbot Endpoint","description":"Chatbot endpoint that can answer questions about PERM cases.\n\nExample questions:\n- \"How many certified cases for April 2024?\"\n- \"How many N pending for April?\" (N = pending cases)\n- \"What is my case G-100-24036-692547?\"\n- \"How long does processing take?\"\n- \"When will May start?\" (month start predictions)\n- \"When will June 2024 start being processed?\"\n- \"Recent cases\"\n- \"Help\" or \"What can you do?\"\n\nSupported status shortcuts:\n- N = Pending/Analyst Review\n- C = Certified  \n- D = Denied\n- W = Withdrawn\n- R = RFI Issued","operationId":"chatbot_endpoint_api_chatbot__post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatbotRequest"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatbotResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/":{"get":{"summary":"Root","description":"Root endpoint.","operationId":"root__get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/health":{"get":{"summary":"Health Check","description":"Health check endpoint.","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"ChatbotLink":{"properties":{"text":{"type":"string","title":"Text"},"url":{"type":"string","title":"Url"},"description":{"type":"string","title":"Description"}},"type":"object","required":["text","url","description"],"title":"ChatbotLink","description":"Link in chatbot response."},"ChatbotRequest":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"ChatbotRequest","description":"Request for chatbot endpoint."},"ChatbotResponse":{"properties":{"response":{"type":"string","title":"Response"},"type":{"type":"string","title":"Type"},"data":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Data"},"links":{"items":{"$ref":"#/components/schemas/ChatbotLink"},"type":"array","title":"Links","default":[]}},"type":"object","required":["response","type"],"title":"ChatbotResponse","description":"Response from chatbot endpoint."},"CompanyCasesRequest":{"properties":{"company_name":{"type":"string","title":"Company Name","description":"Exact company name"},"start_date":{"type":"string","format":"date","title":"Start Date","description":"Start date for case search (minimum: March 1st, 2024)"},"end_date":{"type":"string","format":"date","title":"End Date","description":"End date for case search (maximum: today, 2-week window)"},"limit":{"type":"integer","maximum":1000.0,"minimum":1.0,"title":"Limit","description":"Maximum number of cases to return","default":100},"offset":{"type":"integer","minimum":0.0,"title":"Offset","description":"Offset for pagination","default":0},"recaptcha_token":{"type":"string","title":"Recaptcha Token","description":"Google reCAPTCHA token"}},"type":"object","required":["company_name","start_date","end_date","recaptcha_token"],"title":"CompanyCasesRequest"},"CompanyCasesResponse":{"properties":{"cases":{"items":{"$ref":"#/components/schemas/PermCaseData"},"type":"array","title":"Cases"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"},"company_name":{"type":"string","title":"Company Name"},"date_range":{"additionalProperties":{"type":"string"},"type":"object","title":"Date Range"}},"type":"object","required":["cases","total","limit","offset","company_name","date_range"],"title":"CompanyCasesResponse"},"CompanySearchRequest":{"properties":{"query":{"type":"string","minLength":3,"title":"Query","description":"Company name search query (minimum 3 characters)"},"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","description":"Maximum number of results to return","default":20},"recaptcha_token":{"type":"string","title":"Recaptcha Token","description":"Google reCAPTCHA token"}},"type":"object","required":["query","recaptcha_token"],"title":"CompanySearchRequest"},"CompanySearchResponse":{"properties":{"companies":{"items":{"type":"string"},"type":"array","title":"Companies"},"total":{"type":"integer","title":"Total"},"query":{"type":"string","title":"Query"}},"type":"object","required":["companies","total","query"],"title":"CompanySearchResponse"},"DateSubmissionRequest":{"properties":{"submit_date":{"type":"string","format":"date","title":"Submit Date"},"employer_first_letter":{"type":"string","maxLength":1,"minLength":1,"title":"Employer First Letter","description":"First letter of employer name (A-Z)"},"case_number":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Case Number","description":"Case number for the application (optional)"}},"type":"object","required":["submit_date","employer_first_letter"],"title":"DateSubmissionRequest"},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"PermCaseData":{"properties":{"case_number":{"type":"string","title":"Case Number"},"job_title":{"type":"string","title":"Job Title"},"submit_date":{"type":"string","format":"date","title":"Submit Date"},"employer_name":{"type":"string","title":"Employer Name"},"employer_first_letter":{"type":"string","title":"Employer First Letter"},"status":{"type":"string","title":"Status"}},"type":"object","required":["case_number","job_title","submit_date","employer_name","employer_first_letter","status"],"title":"PermCaseData","description":"Individual PERM case data from perm_cases table."},"UpdatedCasesRequest":{"properties":{"target_date":{"type":"string","format":"date","title":"Target Date","description":"Date to search for case updates (ET timezone). Must be between March 1st, 2024 and today."},"limit":{"type":"integer","maximum":1000.0,"minimum":1.0,"title":"Limit","description":"Maximum number of cases to return","default":100},"offset":{"type":"integer","minimum":0.0,"title":"Offset","description":"Offset for pagination","default":0}},"type":"object","required":["target_date"],"title":"UpdatedCasesRequest"},"UpdatedCasesResponse":{"properties":{"cases":{"items":{"$ref":"#/components/schemas/UpdatedPermCaseData"},"type":"array","title":"Cases"},"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"},"target_date":{"type":"string","title":"Target Date"},"timezone_note":{"type":"string","title":"Timezone Note"}},"type":"object","required":["cases","total","limit","offset","target_date","timezone_note"],"title":"UpdatedCasesResponse"},"UpdatedPermCaseData":{"properties":{"case_number":{"type":"string","title":"Case Number"},"job_title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Job Title"},"submit_date":{"type":"string","format":"date","title":"Submit Date"},"employer_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Employer Name"},"employer_first_letter":{"type":"string","title":"Employer First Letter"},"status":{"type":"string","title":"Status"},"previous_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Previous Status"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["case_number","submit_date","employer_first_letter","status","updated_at"],"title":"UpdatedPermCaseData","description":"Individual PERM case data with update timestamp information."},"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"}}}}