{"openapi":"3.1.0","info":{"title":"Reception Desk","description":"API Gateway for URL Checker Engine","version":"1.0.0"},"paths":{"/check-domains":{"post":{"summary":"Check Domains","description":"Check if domains are on the blocklist.\n\nCalled by frontend before CSV upload to warn users about problematic domains.\n\nBody:\n    {\n        \"domains\": [\"linkedin.com\", \"example.com\", ...]\n    }\n\nReturns:\n    {\n        \"blocked\": [\n            {\n                \"domain\": \"linkedin.com\",\n                \"reason\": \"Legal restrictions - platform blocks automated checks\",\n                \"block_type\": \"legal\",\n                \"error_codes\": [\"999\", \"403\"]\n            }\n        ],\n        \"total_checked\": 150\n    }\n\n**Authentication Required:** User must be signed in.","operationId":"check_domains_check_domains_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Request"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/analyze-csv":{"post":{"summary":"Analyze Csv","description":"Analyze CSV file and categorize URLs before creating a job.\n\nReturns categorized analysis of URLs:\n- valid: Ready to check\n- missing_prefix: Can be fixed by adding https://\n- blocked: On domain blocklist\n- invalid: Malformed, cannot be fixed\n\n**Authentication Required:** User must be signed in.","operationId":"analyze_csv_analyze_csv_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_analyze_csv_analyze_csv_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/public-stats":{"get":{"summary":"Get Public Stats","description":"Aggregate 30-day activity counts for the paywall trust-signal strip.\n\nCached in Redis for 1 hour. The underlying query runs on job-service;\nwe cache because the paywall may be shown many times per hour and this\nendpoint is on the hot path.\n\nUnauthenticated -- numbers are public marketing info.","operationId":"get_public_stats_public_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/domains/health":{"get":{"summary":"Get Domain Health","description":"Get domain health statistics (admin only).\n\nProxied to Job Service.","operationId":"get_domain_health_domains_health_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"sort_by","in":"query","required":false,"schema":{"type":"string","default":"failure_rate","title":"Sort By"}},{"name":"sort_order","in":"query","required":false,"schema":{"type":"string","default":"desc","title":"Sort Order"}},{"name":"min_checks","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Min Checks"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/domains/breakdown":{"get":{"summary":"Get Domain Breakdown","description":"Get status code breakdown for a specific domain (admin only).\n\nProxied to Job Service.","operationId":"get_domain_breakdown_domains_breakdown_get","parameters":[{"name":"domain","in":"query","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/domains/blocked":{"get":{"summary":"Get Blocked Domains","description":"Get list of blocked domains (admin only).\n\nProxied to Job Service.","operationId":"get_blocked_domains_domains_blocked_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"sort_by","in":"query","required":false,"schema":{"type":"string","default":"added_at","title":"Sort By"}},{"name":"sort_order","in":"query","required":false,"schema":{"type":"string","default":"desc","title":"Sort Order"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Add Blocked Domain","description":"Add a domain to the blocklist (admin only).\n\nProxied to Job Service.","operationId":"add_blocked_domain_domains_blocked_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Request"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/domains/blocked/{domain}":{"delete":{"summary":"Remove Blocked Domain","description":"Remove a domain from the blocklist (admin only).\n\nProxied to Job Service.","operationId":"remove_blocked_domain_domains_blocked__domain__delete","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs":{"post":{"summary":"Create Job With Csv","description":"Direct CSV upload. Creates a single job regardless of user balance.\n\nCredit model: deduct min(unique_urls, balance) up front. If the user\ndoesn't have enough to cover the whole upload, the job pauses at the\ncredit ceiling and the user can buy more credits to resume via the\nprogress page.\n\nQuery Parameters:\n    auto_add_prefix: If true, auto-add https:// to URLs missing prefix\n    skip_blocked: If true, skip URLs from blocked domains\n    skip_invalid: If true, skip malformed URLs\n\n**Authentication Required:** User must be signed in.","operationId":"create_job_with_csv_jobs_post","parameters":[{"name":"auto_add_prefix","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Auto Add Prefix"}},{"name":"skip_blocked","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Skip Blocked"}},{"name":"skip_invalid","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Skip Invalid"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/Body_create_job_with_csv_jobs_post"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"List Jobs","description":"Proxy endpoint: List jobs for a user.\nForwards request to job-service.\n\nUses httpx params= kwarg rather than string-concat so plus signs\nin the email (foo+alias@example.com) survive — string-concat sends\na literal '+', which the receiving server decodes as a space and\nfails to match any user.","operationId":"list_jobs_jobs_get","parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","title":"Email"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","title":"Status"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"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"}}}}}}},"/jobs/{job_id}/resume":{"post":{"summary":"Resume Job","description":"Bump the job's credits_allocated by what the user can afford and publish\nthe next batch of URLs to workers. Idempotent via an optimistic-lock\nUPDATE on jobs (concurrent resume requests from the same user will\neither both succeed serialized or one returns 409 without double-charging).\n\nRequires ownership.","operationId":"resume_job_jobs__job_id__resume_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}/pause":{"post":{"summary":"Pause Job Endpoint","description":"User-initiated pause. Only transitions a 'processing' job.","operationId":"pause_job_endpoint_jobs__job_id__pause_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}":{"get":{"summary":"Get Job Status","description":"Get job status and progress.\n\n**Authentication Required:** User must be signed in and own the job.","operationId":"get_job_status_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__routes__JobStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Job","description":"Delete a job permanently.\n\nAuthorization: the requester must either own the job (clerk_user_id\nmatch) OR have the admin role. Anyone else gets 403.\n\nStatus gate: only terminal-state jobs can be deleted (completed,\ncancelled, failed). Running or paused jobs return 409 with a clear\nmessage that they must be cancelled first. This is enforced\nserver-side regardless of how the request arrives — the dashboard\nUI also hides the delete affordance for non-terminal jobs as a\nsecond-line UX guardrail.\n\nRefund policy on delete: only refund unused credits when the job\nended in `failed` (system-side error). For `completed` the math is\nmoot (completed_urls equals credits_allocated, refund = 0). For\n`cancelled` we deliberately do NOT refund — the user already chose\nto abandon at cancel time, and refunding here would backdoor the\nno-refund cancel policy (cancel-then-delete becomes a hidden\nrefund button).","operationId":"delete_job_jobs__job_id__delete","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}/cancel":{"post":{"summary":"Cancel Job","description":"Cancel a running or paused job.\n\nAuthentication required. The user must own the job (job-service's\ncancel endpoint does the ownership check via clerk_user_id, and\nauth here gates access to this proxy in the first place).\n\nPolicy: cancel REFUNDS unused credits. credits_allocated - completed_urls\ngoes back to the owner's balance. Without this, users have no\nincentive to stop a runaway job — they'd rather let it consume\ncredits than cancel for nothing. Standard SaaS cancellation\nsemantics (Stripe, ride-share, prepaid services).\n\nAbuse vector (\"submit big job, cancel for full refund, repeat\"):\nnot actually possible. Cancel doesn't let the user re-upload\ndifferent URLs — the job's URL list is already in the database.\nThe previous no-refund concern was about iteration via DELETE,\nwhich is now blocked entirely (delete requires terminal status).\n\nRefund is idempotent on (transaction_type='refund',\nreference_id=job_id), so a retry after a partial failure won't\ndouble-credit.\n\nEffects:\n- Job status → 'cancelled' (jobs row preserved)\n- Workers honor the job.cancelled event and stop processing\n- Already-completed URL results kept for download/export\n- max(0, credits_allocated - completed_urls) refunded to owner","operationId":"cancel_job_jobs__job_id__cancel_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}/download":{"get":{"summary":"Get Download Link","description":"Get download link for completed job results with optional filters.\n\n**Authentication Required:** User must be signed in and own the job.\n\nQuery Parameters:\n    - status_codes: Comma-separated status codes (e.g., \"404,500\")\n    - non_2xx: Filter for non-2xx status codes\n    - url_contains: Filter URLs containing this text","operationId":"get_download_link_jobs__job_id__download_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"status_codes","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status Codes"}},{"name":"non_2xx","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Non 2Xx"}},{"name":"url_contains","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url Contains"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadLinkResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}/export":{"get":{"summary":"Export Job Results","description":"Export job results as CSV or XLSX (proxies to export-service).\n\n**Authentication Required:** User must be signed in and own the job.\n\nQuery Parameters:\n    - format: Export format - \"csv\" (default) or \"xlsx\"\n    - status_codes: Comma-separated status codes (e.g., \"404,500\")\n    - non_2xx: Filter for non-2xx status codes\n    - url_contains: Filter URLs containing this text","operationId":"export_job_results_jobs__job_id__export_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","default":"csv","title":"Format"}},{"name":"status_codes","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status Codes"}},{"name":"non_2xx","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Non 2Xx"}},{"name":"url_contains","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url Contains"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}/results":{"get":{"summary":"Get Job Results","description":"Proxy endpoint: Get URL check results for a job with optional filters.\nForwards request to job-service.\n\nQuery params:\n    limit: Results per page (default: 50)\n    offset: Skip N results (default: 0)\n    status_codes: Comma-separated status codes to filter (e.g., \"200,404\")\n    non_2xx: Filter for non-2xx status codes only (default: false)\n    url_contains: Filter URLs containing this string (case-insensitive)\n    status_group: One of '2xx','3xx','4xx','5xx','broken','unreachable'.\n        Used by the clickable summary cards on the results page.","operationId":"get_job_results_jobs__job_id__results_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"status_codes","in":"query","required":false,"schema":{"type":"string","title":"Status Codes"}},{"name":"non_2xx","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Non 2Xx"}},{"name":"url_contains","in":"query","required":false,"schema":{"type":"string","title":"Url Contains"}},{"name":"status_group","in":"query","required":false,"schema":{"type":"string","title":"Status Group"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}/url-list":{"get":{"summary":"Get Job Url List","description":"Proxy: return the URLs of a job as newline-separated string.\n\nUsed by the results-page \"Set up monitoring\" CTA to pre-fill the\ncreate-schedule form. Unauthenticated (mirrors /jobs/{id}/results\npattern — owner verification happens at the upstream level).","operationId":"get_job_url_list_jobs__job_id__url_list_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}/filter-options":{"get":{"summary":"Get Job Filter Options","description":"Proxy endpoint: Get available filter options for a job.\nReturns distinct status codes and domains from database.\nForwards request to job-service.","operationId":"get_job_filter_options_jobs__job_id__filter_options_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}/stats":{"get":{"summary":"Get Job Stats","description":"Proxy endpoint: Get job statistics (accurate counts across ALL URLs).\nForwards request to job-service.\n\nCRITICAL: Returns stats for all URLs, not just paginated.\nEssential for large jobs with 50k+ URLs.","operationId":"get_job_stats_jobs__job_id__stats_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/bulk-delete":{"post":{"summary":"Bulk Delete Jobs","description":"Bulk delete jobs.\n\nAuthorization (per-job): owner OR admin. Non-authorized jobs are\nreported in `errors`, never silently dropped.\n\nStatus gate (per-job): only terminal statuses (completed, cancelled,\nfailed) are deletable. Non-terminal jobs are reported in `errors`\nwith a clear \"cancel first\" message.\n\nRefund policy (per-job): only refund unused credits when the job\nended in `failed`. completed = math-moot, cancelled = policy-moot\n(no-refund-on-cancel must apply through delete too).\n\nNote: Using POST instead of DELETE for better HTTP client compatibility.","operationId":"bulk_delete_jobs_jobs_bulk_delete_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/logs":{"get":{"summary":"Get Worker Logs","description":"Proxy endpoint: Get worker logs from monitoring service.","operationId":"get_worker_logs_logs_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","default":100,"title":"Page Size"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string","title":"Domain"}},{"name":"status_code","in":"query","required":false,"schema":{"type":"integer","title":"Status Code"}},{"name":"non_2xx","in":"query","required":false,"schema":{"type":"boolean","title":"Non 2Xx"}},{"name":"has_error","in":"query","required":false,"schema":{"type":"boolean","title":"Has Error"}},{"name":"job_id","in":"query","required":false,"schema":{"type":"string","title":"Job Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Worker Logs Bulk","description":"Proxy endpoint: Bulk delete worker logs.","operationId":"delete_worker_logs_bulk_logs_delete","parameters":[{"name":"job_id","in":"query","required":false,"schema":{"type":"string","title":"Job Id"}},{"name":"domain","in":"query","required":false,"schema":{"type":"string","title":"Domain"}},{"name":"non_2xx","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Non 2Xx"}},{"name":"older_than_hours","in":"query","required":false,"schema":{"type":"integer","title":"Older Than Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/logs/filter-options":{"get":{"summary":"Get Log Filter Options","description":"Proxy endpoint: Get available filter options for logs.","operationId":"get_log_filter_options_logs_filter_options_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/logs/stats":{"get":{"summary":"Get Log Stats","description":"Proxy endpoint: Get log statistics from monitoring service.","operationId":"get_log_stats_logs_stats_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","default":24,"title":"Hours"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/logs/{log_id}":{"delete":{"summary":"Delete Worker Log","description":"Proxy endpoint: Delete a specific worker log.","operationId":"delete_worker_log_logs__log_id__delete","parameters":[{"name":"log_id","in":"path","required":true,"schema":{"type":"string","title":"Log Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/logs/truncate":{"post":{"summary":"Truncate All Logs","description":"Proxy endpoint: Truncate ALL monitoring logs (permanent deletion).\n\nWARNING: This is a destructive operation that deletes ALL logs!","operationId":"truncate_all_logs_logs_truncate_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/proxies":{"get":{"summary":"Get Proxies","description":"Get paginated list of proxies with health stats.\n\nProxied to Proxy Service.","operationId":"get_proxies_proxies_get","parameters":[{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Status"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/proxies/{proxy_id}/blocked-domains":{"get":{"summary":"Get Proxy Blocked Domains","description":"Get blocked/degraded domains for a specific proxy.\n\nProxied to Proxy Service.","operationId":"get_proxy_blocked_domains_proxies__proxy_id__blocked_domains_get","parameters":[{"name":"proxy_id","in":"path","required":true,"schema":{"type":"string","title":"Proxy Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","default":1,"title":"Page"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":10,"title":"Limit"}},{"name":"search","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Search"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/proxies/refresh":{"post":{"summary":"Refresh Proxies","description":"Manually refresh proxy list from Webshare.\n\nProxied to Proxy Service.","operationId":"refresh_proxies_proxies_refresh_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/proxies/stats":{"get":{"summary":"Get Proxy Stats","description":"Get proxy pool statistics.\n\nProxied to Proxy Service.","operationId":"get_proxy_stats_proxies_stats_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/users/me":{"get":{"summary":"Get Current User Profile","description":"Get current user's billing profile and usage stats.\n\nProxied to Billing Service. Forwards X-Real-Client-IP so the\nbilling-service lazy signup-credit grant has a trusted IP for the\n24h abuse throttle (Caddy populates X-Forwarded-For at our edge,\nwhich we read here and re-emit as a dedicated header).","operationId":"get_current_user_profile_users_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me/quota":{"get":{"summary":"Get Current User Quota","description":"Get current user's quota information (usage, limits, trial info).\n\nProxied to Billing Service. Forwards X-Real-Client-IP so the\nlazy signup-credit grant in billing-service has the IP needed to\nrun the abuse throttle.","operationId":"get_current_user_quota_users_me_quota_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me/fingerprint":{"post":{"summary":"Post Current User Fingerprint","description":"Persist the current user's device fingerprint AND, on first call,\ntrigger the deferred signup-bonus grant in billing-service.\n\nThe IP we forward here is the abuse-defense source of truth — Caddy\npopulates X-Forwarded-For with {remote_host} (the real client\nsocket), so we read that rather than the Clerk-webhook IP, which\ncan be a different value.\n\nFrontend posts {os, device_type, screen_size}; any field can be null\nif detection failed in that browser.","operationId":"post_current_user_fingerprint_users_me_fingerprint_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Request"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/paywall-users":{"get":{"summary":"Admin Paywall Users","description":"Get paywall user breakdown.","operationId":"admin_paywall_users_admin_paywall_users_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","default":"30d","title":"Period"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/growth-dashboard":{"get":{"summary":"Admin Growth Dashboard","description":"Get business growth dashboard data.","operationId":"admin_growth_dashboard_admin_growth_dashboard_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","default":"30d","title":"Period"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/revenue-review":{"get":{"summary":"Admin Revenue Review","description":"Revenue review dashboard data for /monitoring/revenue.","operationId":"admin_revenue_review_admin_revenue_review_get","parameters":[{"name":"period","in":"query","required":false,"schema":{"type":"string","default":"30d","title":"Period"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/cohort-table":{"get":{"summary":"Admin Cohort Table","description":"URL-consumption cohort breakdown for /monitoring/cohorts.","operationId":"admin_cohort_table_admin_cohort_table_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/agency-events":{"post":{"summary":"Ingest Agency Event","description":"Record a marketing-site event into agency_events. Closed unless\nMARKETING_INGEST_SECRET matches the header. See module comment.","operationId":"ingest_agency_event_agency_events_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgencyEventIngest"}}},"required":true},"responses":{"202":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/growth-notes":{"post":{"summary":"Admin Add Growth Note","description":"Add a growth note.","operationId":"admin_add_growth_note_admin_growth_notes_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Request"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/growth-notes/{note_id}":{"delete":{"summary":"Admin Delete Growth Note","description":"Delete a growth note.","operationId":"admin_delete_growth_note_admin_growth_notes__note_id__delete","parameters":[{"name":"note_id","in":"path","required":true,"schema":{"type":"string","title":"Note Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/paywall-events":{"post":{"summary":"Record Paywall Event","description":"Record a paywall event from the frontend.","operationId":"record_paywall_event_paywall_events_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Request"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me/credits":{"get":{"summary":"Get Current User Credits","description":"Get current user's credit balance and info.\n\n`credit_balance` is the single available-credit number under the\nunified ledger. `available_credits` is kept as an alias for backward\ncompatibility with frontend code that reads it (paywalls, auto-\nresume); both fields hold the same value.\n\nForwards X-Real-Client-IP so the lazy signup-credit grant in\nbilling-service has the IP needed to run the abuse throttle.","operationId":"get_current_user_credits_users_me_credits_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/credits/packages":{"get":{"summary":"Get Credit Packages","description":"Get available credit packages (proxied to billing-service).","operationId":"get_credit_packages_credits_packages_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/credits/purchase":{"post":{"summary":"Purchase Credits","description":"Create Stripe Checkout session for credit purchase.","operationId":"purchase_credits_credits_purchase_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Request"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me/period-usage":{"get":{"summary":"Get Period Usage","description":"Per-period subscription usage stats (proxied to billing-service).","operationId":"get_period_usage_users_me_period_usage_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/users/me/credit-transactions":{"get":{"summary":"Get Credit Transactions","description":"Get credit transaction history for current user.","operationId":"get_credit_transactions_users_me_credit_transactions_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/checkout/create":{"post":{"summary":"Create Checkout Session","description":"Create Stripe Checkout session for subscription upgrade.\n\nProxied to Billing Service.","operationId":"create_checkout_session_checkout_create_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCheckoutRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/portal/create":{"post":{"summary":"Create Customer Portal Session","description":"Create Stripe Customer Portal session for subscription management.\n\nProxied to Billing Service.","operationId":"create_customer_portal_session_portal_create_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePortalRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/internal/clerk-webhook":{"post":{"summary":"Clerk Webhook Proxy","description":"Proxy Clerk webhook to billing-service.\n\nClerk sends user.created and user.updated events here.\nThis endpoint forwards the webhook to billing-service for processing.","operationId":"clerk_webhook_proxy_internal_clerk_webhook_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/webhooks/stripe":{"post":{"summary":"Stripe Webhook Proxy","description":"Proxy Stripe webhook to billing-service.\n\nStripe sends payment and subscription events here.\nThis endpoint forwards the webhook to billing-service for processing.","operationId":"stripe_webhook_proxy_webhooks_stripe_post","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/admin/users":{"get":{"summary":"Admin Get Users","description":"Get paginated users with activity stats (admin only).\n\nQuery Parameters: see billing-service /users for full list. Notable:\n    only_starred: filter to admin's starred (favorited) users only.","operationId":"admin_get_users_admin_users_get","parameters":[{"name":"hide_deleted","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Hide Deleted"}},{"name":"sort_by","in":"query","required":false,"schema":{"type":"string","default":"pinned","title":"Sort By"}},{"name":"sort_order","in":"query","required":false,"schema":{"type":"string","default":"desc","title":"Sort Order"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"search","in":"query","required":false,"schema":{"type":"string","default":"","title":"Search"}},{"name":"filter_type","in":"query","required":false,"schema":{"type":"string","default":"all","title":"Filter Type"}},{"name":"hide_admin","in":"query","required":false,"schema":{"type":"boolean","default":true,"title":"Hide Admin"}},{"name":"only_starred","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Only Starred"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/{clerk_user_id}":{"get":{"summary":"Admin Get User Detail","description":"Get detailed user info with activity history (admin only).\n\nReturns user profile, subscription info, and recent jobs.","operationId":"admin_get_user_detail_admin_users__clerk_user_id__get","parameters":[{"name":"clerk_user_id","in":"path","required":true,"schema":{"type":"string","title":"Clerk User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"summary":"Admin Update User Limit","description":"Update user's custom usage limit (admin only).\n\nAllows admins to set or clear custom usage limits that override plan defaults.","operationId":"admin_update_user_limit_admin_users__clerk_user_id__patch","parameters":[{"name":"clerk_user_id","in":"path","required":true,"schema":{"type":"string","title":"Clerk User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/{clerk_user_id}/adjust-credits":{"post":{"summary":"Admin Adjust Credits","description":"Admin endpoint to add or remove credits from a user.","operationId":"admin_adjust_credits_admin_users__clerk_user_id__adjust_credits_post","parameters":[{"name":"clerk_user_id","in":"path","required":true,"schema":{"type":"string","title":"Clerk User Id"}},{"name":"amount","in":"query","required":true,"schema":{"type":"integer","title":"Amount"}},{"name":"reason","in":"query","required":false,"schema":{"type":"string","default":"","title":"Reason"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/retention-stats":{"get":{"summary":"Admin Get Retention Stats","description":"Get user retention statistics for admin dashboard (admin only).\n\nReturns cohort analysis, active user metrics, and conversion funnel data.","operationId":"admin_get_retention_stats_admin_retention_stats_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/user-activity/{clerk_user_id}":{"get":{"summary":"Admin Get User Activity","description":"Get activity history for a specific user (admin only).\n\nReturns daily job counts for individual user activity charts.","operationId":"admin_get_user_activity_admin_user_activity__clerk_user_id__get","parameters":[{"name":"clerk_user_id","in":"path","required":true,"schema":{"type":"string","title":"Clerk User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/{clerk_user_id}/notes":{"patch":{"summary":"Admin Update User Notes","description":"Update internal admin notes for a user (admin only).","operationId":"admin_update_user_notes_admin_users__clerk_user_id__notes_patch","parameters":[{"name":"clerk_user_id","in":"path","required":true,"schema":{"type":"string","title":"Clerk User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/{clerk_user_id}/star":{"patch":{"summary":"Admin Toggle User Star","description":"Star or unstar a user — admin's favorites list (admin only).","operationId":"admin_toggle_user_star_admin_users__clerk_user_id__star_patch","parameters":[{"name":"clerk_user_id","in":"path","required":true,"schema":{"type":"string","title":"Clerk User Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/users/{clerk_user_id}/set-usage":{"post":{"summary":"Admin Set User Usage","description":"Manually set user's usage to a specific value (admin only).\n\nThis is used for refunds/adjustments when jobs fail during outages.\nFor example, to refund a user who lost credits during a system failure.\n\nArgs:\n    clerk_user_id: Clerk user ID\n    new_usage: New usage value to set (must be >= 0)\n    reason: Reason for the adjustment (for audit logging)\n    \nReturns:\n    Updated usage stats","operationId":"admin_set_user_usage_admin_users__clerk_user_id__set_usage_post","parameters":[{"name":"clerk_user_id","in":"path","required":true,"schema":{"type":"string","title":"Clerk User Id"}},{"name":"new_usage","in":"query","required":true,"schema":{"type":"integer","title":"New Usage"}},{"name":"reason","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/jobs/{job_id}/rerun":{"post":{"summary":"Admin Rerun Job","description":"Rerun a failed job on behalf of a user (admin only).\n\nThe job will run as if the user created it themselves:\n- Uses the user's quota (checks limits)\n- Increments user's usage counter\n- Email notifications sent to the user\n- All results attributed to the user\n\nThis is useful for reruns after system outages where jobs failed\ndue to infrastructure issues (not user error).\n\nArgs:\n    job_id: Job ID to rerun\n    \nReturns:\n    New job details","operationId":"admin_rerun_job_admin_jobs__job_id__rerun_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/jobs/{job_id}/input-csv":{"get":{"summary":"Admin Get Input Csv","description":"Get a presigned URL to download the original input file for a job (admin only).\n\nSupports both CSV and Excel files. Tries known extensions to find the file.\n\nArgs:\n    job_id: Job ID to get input file for\n\nReturns:\n    Presigned URL valid for 1 hour","operationId":"admin_get_input_csv_admin_jobs__job_id__input_csv_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/backups":{"get":{"summary":"Get Backups","description":"Get list of recent database backups from Redis.","operationId":"get_backups_admin_backups_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Trigger Backup","description":"Trigger a manual database backup (runs in background).","operationId":"trigger_backup_admin_backups_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/maintenance":{"get":{"summary":"Get Maintenance Status","description":"Get current maintenance mode status.","operationId":"get_maintenance_status_admin_maintenance_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"summary":"Toggle Maintenance","description":"Toggle maintenance mode on/off.","operationId":"toggle_maintenance_admin_maintenance_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/services":{"get":{"summary":"Get Services Status","description":"Get live service status from Redis (populated by host cron).","operationId":"get_services_status_admin_services_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}/share":{"post":{"summary":"Create Job Share","description":"Create a public share token for a job. Owner-only.","operationId":"create_job_share_jobs__job_id__share_post","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","default":{},"title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}/shares":{"get":{"summary":"List Job Shares","description":"List all share tokens for a job. Owner-only.","operationId":"list_job_shares_jobs__job_id__shares_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/jobs/{job_id}/share/{token}":{"delete":{"summary":"Revoke Job Share","description":"Revoke a share token. Owner-only.","operationId":"revoke_job_share_jobs__job_id__share__token__delete","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","title":"Job Id"}},{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/share/{token}":{"get":{"summary":"Public Share View","description":"Public read-only access to a shared job. NO authentication required.","operationId":"public_share_view_share__token__get","parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","title":"Token"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","default":0,"title":"Offset"}},{"name":"status_codes","in":"query","required":false,"schema":{"type":"string","title":"Status Codes"}},{"name":"non_2xx","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Non 2Xx"}},{"name":"url_contains","in":"query","required":false,"schema":{"type":"string","title":"Url Contains"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v2/subscription/plans":{"get":{"summary":"List Subscription Plans Proxy","description":"Public — list available subscription tiers.","operationId":"list_subscription_plans_proxy_v2_subscription_plans_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v2/subscription/checkout":{"post":{"summary":"Create Subscription Checkout Proxy","description":"Owner — start Stripe Checkout for a subscription tier.","operationId":"create_subscription_checkout_proxy_v2_subscription_checkout_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v2/subscription/me":{"get":{"summary":"Get My Subscription Proxy","description":"Owner — get the caller's active v2 subscription.","operationId":"get_my_subscription_proxy_v2_subscription_me_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v2/schedules":{"post":{"summary":"Create Schedule Proxy","operationId":"create_schedule_proxy_v2_schedules_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Body"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"List Schedules Proxy","operationId":"list_schedules_proxy_v2_schedules_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v2/schedules/{schedule_id}":{"get":{"summary":"Get Schedule Proxy","operationId":"get_schedule_proxy_v2_schedules__schedule_id__get","parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","title":"Schedule Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"put":{"summary":"Update Schedule Proxy","operationId":"update_schedule_proxy_v2_schedules__schedule_id__put","parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","title":"Schedule Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","title":"Body"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Delete Schedule Proxy","operationId":"delete_schedule_proxy_v2_schedules__schedule_id__delete","parameters":[{"name":"schedule_id","in":"path","required":true,"schema":{"type":"string","title":"Schedule Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/audits":{"post":{"summary":"Create Audit V1","description":"Create a site audit from a sitemap. Used by the dashboard's\n/audit?domain=... entry page when a signed-in user submits a\ndomain from the marketing site's broken-link-monitor CTA.\n\nForwards X-Real-Client-IP + X-Clerk-Email to billing-service so the\nlazy ensure_user_exists hook can create the user row during the\npost-signup Clerk-webhook race window (new users hitting /audit\nimmediately after signing up would otherwise 404 on billing).","operationId":"create_audit_v1_audits_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_CreateAuditBody"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/webhooks/endpoints":{"post":{"summary":"Create Webhook Endpoint V1","description":"Register a new webhook endpoint from the dashboard.\n\nReturns the endpoint metadata plus the signing_secret. The secret\nis only returned here (matches the v2 contract); to rotate, revoke\nand recreate.","operationId":"create_webhook_endpoint_v1_webhooks_endpoints_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_CreateWebhookEndpointBody"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"summary":"List Webhook Endpoints V1","description":"List all webhook endpoints owned by the caller, including revoked ones.","operationId":"list_webhook_endpoints_v1_webhooks_endpoints_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/webhooks/endpoints/{endpoint_id}":{"get":{"summary":"Get Webhook Endpoint V1","operationId":"get_webhook_endpoint_v1_webhooks_endpoints__endpoint_id__get","parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"summary":"Update Webhook Endpoint V1","operationId":"update_webhook_endpoint_v1_webhooks_endpoints__endpoint_id__patch","parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/_UpdateWebhookEndpointBody"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"summary":"Revoke Webhook Endpoint V1","description":"Soft-revoke the endpoint. Pending deliveries are dropped on the\nnext worker poll; delivery history stays for audit. Create a new\nendpoint if a fresh signing secret is needed.","operationId":"revoke_webhook_endpoint_v1_webhooks_endpoints__endpoint_id__delete","parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/admin/live-activity":{"get":{"summary":"Admin Live Activity","description":"Live snapshot of URL-check activity for the monitoring overview page.","operationId":"admin_live_activity_admin_live_activity_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/jobs":{"post":{"tags":["agent-api"],"summary":"Submit Job","description":"Create a new URL-checking job from a list of URLs.\n\nBehavior:\n  - URLs must include scheme (http:// or https://). Invalid URLs are\n    silently dropped and counted in the response's `invalid_urls_rejected`.\n  - Duplicate URLs are deduplicated; `duplicates_removed` in response.\n  - Hard cap: 75,000 URLs per job (same as the web UI).\n  - Credits: we deduct min(total_urls, balance). If the balance is\n    less than total_urls the job creates in 'paused' at the credit\n    ceiling; the caller can add credits and poll status to see it\n    resume on its own (same behavior as the web UI).\n\nIdempotency:\n  - If the client sends an `Idempotency-Key` header, the response\n    is cached for 24 hours. A retry with the same key returns the\n    original response (same job_id, same credits_allocated) instead\n    of creating a duplicate job. Different body + same key returns\n    409 conflict. Convention: generate a UUIDv4 per logical\n    request and reuse it on retries.","operationId":"submit_job_api_v2_jobs_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitJobRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitJobResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/jobs/wait":{"post":{"tags":["agent-api"],"summary":"Submit And Wait","description":"Submit URLs and block until the job finishes (or `wait_seconds` elapses).\nOn completion, returns the job summary plus the full results list.\nOn timeout, returns `timed_out=true` and partial results — the caller\ncan finish the work asynchronously via `GET /jobs/{id}/results`.\n\nBest for small-to-medium URL lists (≤2,000 typical, hard ceiling\nenforced upstream at MAX_URLS_PER_JOB). For large jobs, use the\nsubmit + poll pattern: it's resilient to proxy timeouts and\nserverless cold-starts.","operationId":"submit_and_wait_api_v2_jobs_wait_post","parameters":[{"name":"wait_seconds","in":"query","required":false,"schema":{"type":"integer","maximum":900,"minimum":1,"description":"Max seconds to block waiting for completion. Default 60, cap 900.","default":60,"title":"Wait Seconds"},"description":"Max seconds to block waiting for completion. Default 60, cap 900."},{"name":"poll_interval","in":"query","required":false,"schema":{"type":"number","maximum":10.0,"minimum":0.5,"description":"Seconds between status polls while waiting. Default 2.","default":2.0,"title":"Poll Interval"},"description":"Seconds between status polls while waiting. Default 2."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubmitJobRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","title":"Response Submit And Wait Api V2 Jobs Wait Post"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/jobs/{job_id}":{"get":{"tags":["agent-api"],"summary":"Get Job Status","description":"Current status of a job owned by the caller. 404 if not owned or missing.","operationId":"get_job_status_api_v2_jobs__job_id__get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/src__api__v2__routes_jobs__JobStatusResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["agent-api"],"summary":"Cancel Job","description":"Cancel a running job and refund unprocessed credits.\n\nDelegates to the same cancel endpoint the web UI uses so refund\nlogic stays consistent across auth paths.","operationId":"cancel_job_api_v2_jobs__job_id__delete","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/jobs/{job_id}/results":{"get":{"tags":["agent-api"],"summary":"Get Job Results","description":"Paginated results for a job. Two modes:\n\n  1. Offset/limit (default): `?limit=100&offset=200`. Simple but\n     the page contents can shift if results change between calls\n     (e.g., a new URL finishes checking). Fine for one-shot fetches.\n\n  2. Cursor (recommended for full exports): omit `offset`, pass\n     `cursor=` (and `limit=`). The response's `next_cursor`\n     field carries the cursor for the next page; null means the\n     end of the stream. Pages are stable under concurrent writes.\n\nOwnership is checked before proxying to job-service. The underlying\npage size caps at 1000 so a single request is bounded.","operationId":"get_job_results_api_v2_jobs__job_id__results_get","parameters":[{"name":"job_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Job Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":1000,"minimum":1,"default":100,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"cursor","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"Opaque cursor from a previous response's `next_cursor`. When set, results are returned in stable id-asc order and `offset` is ignored. Pagination ends when `next_cursor` is null in the response.","title":"Cursor"},"description":"Opaque cursor from a previous response's `next_cursor`. When set, results are returned in stable id-asc order and `offset` is ignored. Pagination ends when `next_cursor` is null in the response."},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JobResultsResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/usage":{"get":{"tags":["agent-api"],"summary":"Get Usage","description":"Current credit balance for the key owner.","operationId":"get_usage_api_v2_usage_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/keys":{"post":{"tags":["api-keys"],"summary":"Create Api Key","description":"Mint a new API key. The plaintext `key` field in the response is\nshown ONCE. Caller must copy it immediately -- we never show it again.","operationId":"create_api_key_api_v2_keys_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateKeyRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateKeyResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["api-keys"],"summary":"List Api Keys","description":"List the caller's active (non-revoked) API keys.","operationId":"list_api_keys_api_v2_keys_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/KeyListItem"},"title":"Response List Api Keys Api V2 Keys Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/keys/{key_id}":{"delete":{"tags":["api-keys"],"summary":"Revoke Api Key","description":"Soft-revoke a key. 404 if the key doesn't exist OR isn't owned by\nthe caller (we don't distinguish -- leaks less info to attackers).","operationId":"revoke_api_key_api_v2_keys__key_id__delete","parameters":[{"name":"key_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Key Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/webhooks/endpoints":{"post":{"tags":["agent-api"],"summary":"Create Endpoint","description":"Register a new webhook endpoint.\n\nReturns the endpoint metadata plus the signing_secret. Save the\nsecret somewhere safe -- it's only returned here. The receiving\nservice must use it to verify incoming Bulkurlchecker-Signature\nheaders (HMAC-SHA256 over `<timestamp>.<raw_body>`).","operationId":"create_endpoint_api_v2_webhooks_endpoints_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateEndpointRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatedEndpointResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"get":{"tags":["agent-api"],"summary":"List Endpoints","description":"List all webhook endpoints owned by the caller, including revoked ones.","operationId":"list_endpoints_api_v2_webhooks_endpoints_get","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EndpointResponse"},"title":"Response List Endpoints Api V2 Webhooks Endpoints Get"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/webhooks/endpoints/{endpoint_id}":{"get":{"tags":["agent-api"],"summary":"Get Endpoint","operationId":"get_endpoint_api_v2_webhooks_endpoints__endpoint_id__get","parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndpointResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["agent-api"],"summary":"Update Endpoint","operationId":"update_endpoint_api_v2_webhooks_endpoints__endpoint_id__patch","parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateEndpointRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EndpointResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["agent-api"],"summary":"Revoke Endpoint","description":"Soft-revoke the endpoint. Pending deliveries are dropped on the\nnext worker poll. Delivery history stays for audit; create a new\nendpoint if you need a fresh secret.","operationId":"revoke_endpoint_api_v2_webhooks_endpoints__endpoint_id__delete","parameters":[{"name":"endpoint_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Endpoint Id"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"204":{"description":"Successful Response"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/monitor/summary":{"get":{"tags":["monitor"],"summary":"Summary","description":"Aggregate metrics over the trailing window.","operationId":"summary_api_v2_monitor_summary_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":720,"minimum":1,"default":24,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/monitor/recent":{"get":{"tags":["monitor"],"summary":"Recent","description":"Most-recent request log rows, newest first.","operationId":"recent_api_v2_monitor_recent_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":500,"minimum":1,"default":50,"title":"Limit"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/monitor/endpoints":{"get":{"tags":["monitor"],"summary":"Per Endpoint","description":"Request count + error count grouped by method+path.","operationId":"per_endpoint_api_v2_monitor_endpoints_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":720,"minimum":1,"default":24,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/monitor/keys":{"get":{"tags":["monitor"],"summary":"Per Key","description":"Per-key usage over the window.","operationId":"per_key_api_v2_monitor_keys_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":720,"minimum":1,"default":24,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/monitor/channels":{"get":{"tags":["monitor"],"summary":"Per Channel","description":"Per-channel breakdown (web/api/sdk/mcp) over the trailing window.\n\nPowers the /monitoring/channels admin dashboard. Surfaces volume,\nerror rate, p95 latency, and unique-user counts per channel so the\noperator can answer 'how is each channel doing today?' at a glance.","operationId":"per_channel_api_v2_monitor_channels_get","parameters":[{"name":"hours","in":"query","required":false,"schema":{"type":"integer","maximum":720,"minimum":1,"default":24,"title":"Hours"}},{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/api/v2/audits":{"post":{"tags":["agent-api"],"summary":"Create Audit","operationId":"create_audit_api_v2_audits_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAuditRequest"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateAuditResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/.well-known/oauth-authorization-server":{"get":{"tags":["oauth"],"summary":"Oauth Authorization Server Metadata","description":"RFC 8414 authorization server metadata document.","operationId":"oauth_authorization_server_metadata__well_known_oauth_authorization_server_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/oauth/register":{"post":{"tags":["oauth"],"summary":"Register Client","description":"Public, unauthenticated endpoint. Every MCP client instance calls\nthis once to get its client_id. No client_secret is issued (public\nclients use PKCE instead).","operationId":"register_client_oauth_register_post","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClientRegistrationRequest"}}},"required":true},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/authorize":{"get":{"tags":["oauth"],"summary":"Authorize","description":"Entry point for the browser. We validate the request params, then\nbounce the user to the frontend /oauth/consent page which handles\nClerk login + shows the consent UI + posts back to /oauth/approve.\n\nThe frontend preserves ALL the query params so we can reconstruct\nthe auth_code request after the user clicks Allow.","operationId":"authorize_oauth_authorize_get","parameters":[{"name":"response_type","in":"query","required":true,"schema":{"type":"string","title":"Response Type"}},{"name":"client_id","in":"query","required":true,"schema":{"type":"string","title":"Client Id"}},{"name":"redirect_uri","in":"query","required":true,"schema":{"type":"string","title":"Redirect Uri"}},{"name":"code_challenge","in":"query","required":true,"schema":{"type":"string","title":"Code Challenge"}},{"name":"code_challenge_method","in":"query","required":false,"schema":{"type":"string","default":"S256","title":"Code Challenge Method"}},{"name":"scope","in":"query","required":false,"schema":{"type":"string","default":"full","title":"Scope"}},{"name":"state","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"}},{"name":"resource","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/approve":{"post":{"tags":["oauth"],"summary":"Approve","description":"Frontend consent page POSTs here after the user clicks \"Allow\".\nRequires Clerk JWT (the user must be logged in to our platform).\nReturns the redirect URL the frontend should then navigate to\n(which lands the user back on the MCP client with ?code=...).","operationId":"approve_oauth_approve_post","parameters":[{"name":"authorization","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Authorization"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApproveRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/token":{"post":{"tags":["oauth"],"summary":"Token","description":"Exchange an authorization code for an access token.\nPublic clients: no client_secret; PKCE verifier required.","operationId":"token_oauth_token_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_token_oauth_token_post"}}},"required":true},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/oauth/revoke":{"post":{"tags":["oauth"],"summary":"Revoke","description":"RFC 7009 token revocation. Always returns 200 (per spec, even if\nthe token doesn't exist or was already revoked -- don't leak which).","operationId":"revoke_oauth_revoke_post","requestBody":{"content":{"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/Body_revoke_oauth_revoke_post"}}},"required":true},"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 Check","description":"Health check endpoint.","operationId":"health_check_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"AgencyEventIngest":{"properties":{"event_type":{"type":"string","title":"Event Type"},"email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Email"},"agency_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Agency Name"},"client_count_estimate":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Count Estimate"},"current_tools":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Current Tools"},"source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Source"}},"type":"object","required":["event_type"],"title":"AgencyEventIngest"},"ApproveRequest":{"properties":{"client_id":{"type":"string","title":"Client Id"},"redirect_uri":{"type":"string","title":"Redirect Uri"},"code_challenge":{"type":"string","title":"Code Challenge"},"code_challenge_method":{"type":"string","title":"Code Challenge Method","default":"S256"},"scope":{"type":"string","title":"Scope","default":"full"},"state":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"State"},"resource":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Resource"}},"type":"object","required":["client_id","redirect_uri","code_challenge"],"title":"ApproveRequest"},"Body_analyze_csv_analyze_csv_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_analyze_csv_analyze_csv_post"},"Body_create_job_with_csv_jobs_post":{"properties":{"file":{"type":"string","format":"binary","title":"File"}},"type":"object","required":["file"],"title":"Body_create_job_with_csv_jobs_post"},"Body_revoke_oauth_revoke_post":{"properties":{"token":{"type":"string","title":"Token"}},"type":"object","required":["token"],"title":"Body_revoke_oauth_revoke_post"},"Body_token_oauth_token_post":{"properties":{"grant_type":{"type":"string","title":"Grant Type"},"code":{"type":"string","title":"Code"},"redirect_uri":{"type":"string","title":"Redirect Uri"},"client_id":{"type":"string","title":"Client Id"},"code_verifier":{"type":"string","title":"Code Verifier"}},"type":"object","required":["grant_type","code","redirect_uri","client_id","code_verifier"],"title":"Body_token_oauth_token_post"},"ClientRegistrationRequest":{"properties":{"client_name":{"type":"string","maxLength":120,"title":"Client Name"},"redirect_uris":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Redirect Uris"},"software_id":{"anyOf":[{"type":"string","maxLength":120},{"type":"null"}],"title":"Software Id"},"software_version":{"anyOf":[{"type":"string","maxLength":40},{"type":"null"}],"title":"Software Version"},"token_endpoint_auth_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Token Endpoint Auth Method"},"grant_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Grant Types"},"response_types":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Response Types"},"scope":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Scope"},"client_uri":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Client Uri"}},"type":"object","required":["client_name","redirect_uris"],"title":"ClientRegistrationRequest","description":"RFC 7591 registration payload. We accept only the subset MCP clients\nactually send."},"CreateAuditRequest":{"properties":{"domain":{"type":"string","maxLength":255,"title":"Domain","description":"The domain to audit, e.g. 'https://example.com'. SSRF defense rejects private and loopback addresses."},"label":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Label","description":"Optional human-readable label for the audit job."}},"type":"object","required":["domain"],"title":"CreateAuditRequest"},"CreateAuditResponse":{"properties":{"job_id":{"type":"string","title":"Job Id"},"domain":{"type":"string","title":"Domain"},"audit_source":{"type":"string","title":"Audit Source"},"sitemap_url":{"type":"string","title":"Sitemap Url"},"total_urls":{"type":"integer","title":"Total Urls"},"credits_allocated":{"type":"integer","title":"Credits Allocated"},"status":{"type":"string","title":"Status"}},"type":"object","required":["job_id","domain","audit_source","sitemap_url","total_urls","credits_allocated","status"],"title":"CreateAuditResponse"},"CreateCheckoutRequest":{"properties":{"plan_tier":{"type":"string","title":"Plan Tier"},"success_url":{"type":"string","title":"Success Url"},"cancel_url":{"type":"string","title":"Cancel Url"}},"type":"object","required":["plan_tier","success_url","cancel_url"],"title":"CreateCheckoutRequest"},"CreateEndpointRequest":{"properties":{"url":{"type":"string","maxLength":2083,"minLength":1,"format":"uri","title":"Url","description":"Destination URL. Must be HTTPS in production (http:// allowed for localhost/loopback during dev)."},"label":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Label","description":"Optional human-readable label, shown in the dashboard."},"events":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Events","description":"Optional event-type allowlist. Empty/omitted = subscribe to every supported event. Currently the only event is 'job.completed'."}},"type":"object","required":["url"],"title":"CreateEndpointRequest"},"CreateKeyRequest":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name","description":"Human label for the key"}},"type":"object","required":["name"],"title":"CreateKeyRequest"},"CreateKeyResponse":{"properties":{"id":{"type":"string","title":"Id"},"key":{"type":"string","title":"Key","description":"Plaintext API key -- shown ONCE. Store it now."},"key_prefix":{"type":"string","title":"Key Prefix"},"name":{"type":"string","title":"Name"},"created_at":{"type":"string","title":"Created At"}},"type":"object","required":["id","key","key_prefix","name","created_at"],"title":"CreateKeyResponse"},"CreatePortalRequest":{"properties":{"return_url":{"type":"string","title":"Return Url"}},"type":"object","required":["return_url"],"title":"CreatePortalRequest"},"CreatedEndpointResponse":{"properties":{"id":{"type":"string","title":"Id"},"url":{"type":"string","title":"Url"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"events":{"items":{"type":"string"},"type":"array","title":"Events"},"enabled":{"type":"boolean","title":"Enabled"},"created_at":{"type":"string","title":"Created At"},"revoked_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revoked At"},"signing_secret":{"type":"string","title":"Signing Secret"}},"type":"object","required":["id","url","events","enabled","created_at","signing_secret"],"title":"CreatedEndpointResponse","description":"Same as EndpointResponse but with the signing secret. Returned\nONLY on POST so the user can copy it once."},"DownloadLinkResponse":{"properties":{"downloadUrl":{"type":"string","title":"Downloadurl"}},"type":"object","required":["downloadUrl"],"title":"DownloadLinkResponse"},"EndpointResponse":{"properties":{"id":{"type":"string","title":"Id"},"url":{"type":"string","title":"Url"},"label":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Label"},"events":{"items":{"type":"string"},"type":"array","title":"Events"},"enabled":{"type":"boolean","title":"Enabled"},"created_at":{"type":"string","title":"Created At"},"revoked_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Revoked At"}},"type":"object","required":["id","url","events","enabled","created_at"],"title":"EndpointResponse","description":"Endpoint as visible to the client. Never includes signing_secret."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"JobResultsResponse":{"properties":{"job_id":{"type":"string","title":"Job Id"},"total":{"type":"integer","title":"Total"},"offset":{"type":"integer","title":"Offset"},"limit":{"type":"integer","title":"Limit"},"results":{"items":{"$ref":"#/components/schemas/UrlResult"},"type":"array","title":"Results"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"type":"object","required":["job_id","total","offset","limit","results"],"title":"JobResultsResponse"},"KeyListItem":{"properties":{"id":{"type":"string","title":"Id"},"key_prefix":{"type":"string","title":"Key Prefix"},"name":{"type":"string","title":"Name"},"scopes":{"items":{"type":"string"},"type":"array","title":"Scopes"},"last_used_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Used At"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"}},"type":"object","required":["id","key_prefix","name","scopes"],"title":"KeyListItem"},"SubmitJobRequest":{"properties":{"urls":{"items":{"type":"string"},"type":"array","minItems":1,"title":"Urls","description":"List of URLs to check. Each URL must include an explicit http:// or https:// scheme. Duplicates are removed."},"name":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Name","description":"Optional human-readable label for this job. Reserved -- not yet persisted."}},"type":"object","required":["urls"],"title":"SubmitJobRequest"},"SubmitJobResponse":{"properties":{"job_id":{"type":"string","title":"Job Id"},"status":{"type":"string","title":"Status"},"total_urls":{"type":"integer","title":"Total Urls"},"credits_allocated":{"type":"integer","title":"Credits Allocated"},"duplicates_removed":{"type":"integer","title":"Duplicates Removed"},"invalid_urls_rejected":{"type":"integer","title":"Invalid Urls Rejected"}},"type":"object","required":["job_id","status","total_urls","credits_allocated","duplicates_removed","invalid_urls_rejected"],"title":"SubmitJobResponse"},"UpdateEndpointRequest":{"properties":{"url":{"anyOf":[{"type":"string","maxLength":2083,"minLength":1,"format":"uri"},{"type":"null"}],"title":"Url"},"label":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Label"},"events":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Events"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"}},"type":"object","title":"UpdateEndpointRequest"},"UrlResult":{"properties":{"url":{"type":"string","title":"Url"},"status_code":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Status Code"},"response_time":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Response Time"},"final_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Final Url"},"error":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error"},"is_soft_404":{"type":"boolean","title":"Is Soft 404","default":false}},"type":"object","required":["url"],"title":"UrlResult"},"UsageResponse":{"properties":{"credit_balance":{"type":"integer","title":"Credit Balance"}},"type":"object","required":["credit_balance"],"title":"UsageResponse"},"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"},"_CreateAuditBody":{"properties":{"domain":{"type":"string","maxLength":255,"title":"Domain"}},"type":"object","required":["domain"],"title":"_CreateAuditBody"},"_CreateWebhookEndpointBody":{"properties":{"url":{"type":"string","maxLength":2000,"title":"Url"},"label":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Label"},"events":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Events"}},"type":"object","required":["url"],"title":"_CreateWebhookEndpointBody"},"_UpdateWebhookEndpointBody":{"properties":{"url":{"anyOf":[{"type":"string","maxLength":2000},{"type":"null"}],"title":"Url"},"label":{"anyOf":[{"type":"string","maxLength":200},{"type":"null"}],"title":"Label"},"events":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Events"},"enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Enabled"}},"type":"object","title":"_UpdateWebhookEndpointBody"},"src__api__routes__JobStatusResponse":{"properties":{"id":{"type":"string","title":"Id"},"user_email":{"type":"string","title":"User Email"},"csv_path":{"type":"string","title":"Csv Path"},"total_urls":{"type":"integer","title":"Total Urls"},"completed_urls":{"type":"integer","title":"Completed Urls"},"status":{"type":"string","title":"Status"},"created_at":{"type":"string","title":"Created At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"},"credits_allocated":{"type":"integer","title":"Credits Allocated","default":0},"paused_by_user":{"type":"boolean","title":"Paused By User","default":false},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"audit_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Audit Source"}},"type":"object","required":["id","user_email","csv_path","total_urls","completed_urls","status","created_at"],"title":"JobStatusResponse"},"src__api__v2__routes_jobs__JobStatusResponse":{"properties":{"job_id":{"type":"string","title":"Job Id"},"status":{"type":"string","title":"Status"},"total_urls":{"type":"integer","title":"Total Urls"},"completed_urls":{"type":"integer","title":"Completed Urls"},"credits_allocated":{"type":"integer","title":"Credits Allocated"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"started_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Started At"},"completed_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Completed At"}},"type":"object","required":["job_id","status","total_urls","completed_urls","credits_allocated"],"title":"JobStatusResponse"}}}}