{"openapi":"3.0.0","info":{"title":"Bloqr API","version":"2.0.0","description":"Compiler-as-a-Service for adblock filter lists. Transform, optimize, and combine filter lists from multiple sources with real-time progress tracking.","license":{"name":"GPL-3.0","url":"https://github.com/jaypatrick/adblock-compiler/blob/master/LICENSE"},"contact":{"name":"Jayson Knight","url":"https://github.com/jaypatrick/adblock-compiler"}},"servers":[{"url":"https://api.bloqr.jaysonknight.com","description":"Production server"}],"components":{"schemas":{},"parameters":{}},"paths":{"/api":{"get":{"tags":["Meta"],"summary":"Get API information","description":"Returns general information about the Adblock Compiler API, including available endpoints and features","responses":{"200":{"description":"API information","content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"},"description":{"type":"string"},"repository":{"type":"string"},"endpoints":{"type":"object","properties":{"compile":{"type":"string"},"validate":{"type":"string"},"ast":{"type":"string"},"monitoring":{"type":"string"},"configuration":{"type":"string"},"documentation":{"type":"string"},"openapi":{"type":"string"}},"required":["compile","validate","ast","monitoring","configuration","documentation","openapi"]},"features":{"type":"array","items":{"type":"string"}},"authentication":{"type":"object","properties":{"methods":{"type":"array","items":{"type":"string"}},"providers":{"type":"string"}},"required":["methods","providers"]}},"required":["name","version","description","repository","endpoints","features","authentication"]}}}}}}},"/api/version":{"get":{"tags":["Meta"],"summary":"Get API version","description":"Returns the current API version and deployment information from the latest successful deployment","responses":{"200":{"description":"Version information","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"version":{"type":"string"},"buildNumber":{"type":"string"},"fullVersion":{"type":"string"},"gitCommit":{"type":"string","nullable":true},"gitBranch":{"type":"string","nullable":true},"deployedAt":{"type":"string","format":"date-time"},"deployedBy":{"type":"string","nullable":true},"status":{"type":"string"},"metadata":{"nullable":true},"message":{"type":"string"}},"required":["success"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"},"version":{"type":"string"}},"required":["success","error","version"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"},"version":{"type":"string"}},"required":["success","error","version"]}}}}}}},"/api/schemas":{"get":{"tags":["Meta"],"summary":"Get validation schemas","description":"Returns all Zod validation schemas used by the API for request/response validation","responses":{"200":{"description":"Validation schemas","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"schemas":{"type":"object","additionalProperties":{"nullable":true}}},"required":["success","schemas"]}}}}}}},"/api/deployments":{"get":{"tags":["Meta"],"summary":"List deployment history","description":"Returns deployment history, optionally filtered by version, status, or branch","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":1000,"default":50,"description":"Maximum number of deployments to return"},"required":false,"description":"Maximum number of deployments to return","name":"limit","in":"query"},{"schema":{"type":"string","description":"Filter by version"},"required":false,"description":"Filter by version","name":"version","in":"query"},{"schema":{"type":"string","description":"Filter by deployment status (success, failed)"},"required":false,"description":"Filter by deployment status (success, failed)","name":"status","in":"query"},{"schema":{"type":"string","description":"Filter by git branch"},"required":false,"description":"Filter by git branch","name":"branch","in":"query"}],"responses":{"200":{"description":"Deployment history","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"deployments":{"type":"array","items":{"type":"object","properties":{"version":{"type":"string"},"buildNumber":{"type":"string"},"fullVersion":{"type":"string"},"gitCommit":{"type":"string","nullable":true},"gitBranch":{"type":"string","nullable":true},"deployedAt":{"type":"string","format":"date-time"},"deployedBy":{"type":"string","nullable":true},"status":{"type":"string"},"metadata":{"nullable":true}},"required":["version","buildNumber","fullVersion","gitCommit","gitBranch","deployedAt","deployedBy","status"]}},"count":{"type":"integer","minimum":0}},"required":["success","deployments","count"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/deployments/stats":{"get":{"tags":["Meta"],"summary":"Get deployment statistics","description":"Returns aggregate deployment statistics including total, successful, and failed deployment counts","responses":{"200":{"description":"Deployment statistics","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"totalDeployments":{"type":"integer","minimum":0},"successfulDeployments":{"type":"integer","minimum":0},"failedDeployments":{"type":"integer","minimum":0},"latestVersion":{"type":"string","nullable":true}},"required":["success","totalDeployments","successfulDeployments","failedDeployments","latestVersion"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/turnstile-config":{"get":{"tags":["Meta"],"summary":"Get Cloudflare Turnstile configuration","description":"Returns public Turnstile site key and whether Turnstile verification is enabled","responses":{"200":{"description":"Turnstile configuration","content":{"application/json":{"schema":{"type":"object","properties":{"siteKey":{"type":"string","nullable":true},"enabled":{"type":"boolean"}},"required":["siteKey","enabled"]}}}}}}},"/api/sentry-config":{"get":{"tags":["Meta"],"summary":"Get Sentry configuration","description":"Returns public Sentry DSN and environment for frontend error tracking","responses":{"200":{"description":"Sentry configuration","content":{"application/json":{"schema":{"type":"object","properties":{"dsn":{"type":"string","nullable":true},"environment":{"type":"string"},"enabled":{"type":"boolean"}},"required":["dsn","environment","enabled"]}}}}}}},"/api/auth/providers":{"get":{"tags":["Meta"],"summary":"Get available auth providers","description":"Returns which authentication providers are currently active (email/password, GitHub, Google)","responses":{"200":{"description":"Auth providers configuration","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"emailPassword":{"type":"boolean"},"github":{"type":"boolean"},"google":{"type":"boolean"}},"required":["success","emailPassword","github","google"]}}}}}}},"/api/compile":{"post":{"tags":["Compile"],"summary":"Compile filter lists","description":"Compiles adblock filter lists with JSON response","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"configuration":{"type":"object","additionalProperties":{"nullable":true}},"preFetchedContent":{"type":"object","additionalProperties":{"type":"string"}},"benchmark":{"type":"boolean"},"priority":{"type":"string","enum":["low","normal","high"]},"turnstileToken":{"type":"string"}},"required":["configuration"]}}}},"responses":{"200":{"description":"Compilation successful","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"result":{"type":"object","properties":{"output":{"type":"string"},"stats":{"type":"object","properties":{"total":{"type":"number"},"processed":{"type":"number"},"failed":{"type":"number"}},"required":["total","processed","failed"]},"benchmark":{"type":"object","additionalProperties":{"nullable":true}}},"required":["output"]}},"required":["success","result"]}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/compile/stream":{"post":{"tags":["Compile"],"summary":"Compile with streaming","description":"Compiles filter lists with Server-Sent Events streaming","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"configuration":{"type":"object","additionalProperties":{"nullable":true}},"preFetchedContent":{"type":"object","additionalProperties":{"type":"string"}},"benchmark":{"type":"boolean"},"priority":{"type":"string","enum":["low","normal","high"]},"turnstileToken":{"type":"string"}},"required":["configuration"]}}}},"responses":{"200":{"description":"Streaming response started","content":{"text/event-stream":{"schema":{"type":"string"}}}}}}},"/api/compile/batch":{"post":{"tags":["Compile"],"summary":"Batch compile","description":"Compiles multiple filter lists in a single request","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"requests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"configuration":{"type":"object","additionalProperties":{"nullable":true}},"preFetchedContent":{"type":"object","additionalProperties":{"type":"string"}},"benchmark":{"type":"boolean"}},"required":["id","configuration"]}},"priority":{"type":"string","enum":["low","normal","high"]},"turnstileToken":{"type":"string"}},"required":["requests"]}}}},"responses":{"200":{"description":"Batch compilation results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"success":{"type":"boolean"},"result":{"nullable":true},"error":{"type":"string"}},"required":["id","success"]}}},"required":["success","results"]}}}}}}},"/api/ast/parse":{"post":{"tags":["Compile"],"summary":"Parse filter list AST","description":"Parses filter list rules into an Abstract Syntax Tree","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"rules":{"type":"array","items":{"type":"string"}},"includeMetadata":{"type":"boolean"}},"required":["rules"]}}}},"responses":{"200":{"description":"Parsed AST","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"ast":{"type":"array","items":{"nullable":true}}},"required":["success","ast"]}}}}}}},"/api/validate":{"post":{"tags":["Compile"],"summary":"Validate filter list","description":"Validates filter list rules without compilation","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"rules":{"type":"array","items":{"type":"string"}},"strict":{"type":"boolean"}},"required":["rules"]}}}},"responses":{"200":{"description":"Validation results","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"object","properties":{"line":{"type":"number"},"message":{"type":"string"}},"required":["line","message"]}}},"required":["success","valid"]}}}}}}},"/api/ws/compile":{"get":{"tags":["Compile"],"summary":"WebSocket compile endpoint","description":"WebSocket endpoint for real-time compilation updates","parameters":[{"schema":{"type":"string"},"required":false,"name":"turnstileToken","in":"query"}],"responses":{"101":{"description":"WebSocket upgrade successful"},"403":{"description":"Turnstile verification failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/validate-rule":{"post":{"tags":["Compile"],"summary":"Validate single rule","description":"Validates a single filter list rule","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"rule":{"type":"string"}},"required":["rule"]}}}},"responses":{"200":{"description":"Validation result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"valid":{"type":"boolean"},"error":{"type":"string"}},"required":["success","valid"]}}}}}}},"/api/diff":{"post":{"tags":["Compile"],"summary":"Diff two filter lists","description":"Compares two filter lists and returns added, removed, and domain-level changes using the AGTree AST diff engine.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"original":{"type":"array","items":{"type":"string"},"minItems":1},"current":{"type":"array","items":{"type":"string"},"minItems":1},"options":{"type":"object","properties":{"ignoreComments":{"type":"boolean"},"ignoreEmptyLines":{"type":"boolean"},"analyzeDomains":{"type":"boolean"},"includeFullRules":{"type":"boolean"},"maxRulesToInclude":{"type":"integer","minimum":1,"maximum":10000}}}},"required":["original","current"]}}}},"responses":{"200":{"description":"Diff generated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"parseErrors":{"type":"object","properties":{"original":{"type":"array","items":{"type":"object","properties":{"line":{"type":"number"},"rule":{"type":"string"},"message":{"type":"string"}},"required":["line","rule","message"]}},"current":{"type":"array","items":{"type":"object","properties":{"line":{"type":"number"},"rule":{"type":"string"},"message":{"type":"string"}},"required":["line","rule","message"]}}},"required":["original","current"]},"report":{"type":"object","properties":{"timestamp":{"type":"string"},"generatorVersion":{"type":"string"},"original":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"},"timestamp":{"type":"string"},"ruleCount":{"type":"number"}},"required":["ruleCount"]},"current":{"type":"object","properties":{"name":{"type":"string"},"version":{"type":"string"},"timestamp":{"type":"string"},"ruleCount":{"type":"number"}},"required":["ruleCount"]},"summary":{"type":"object","properties":{"originalCount":{"type":"number"},"newCount":{"type":"number"},"addedCount":{"type":"number"},"removedCount":{"type":"number"},"unchangedCount":{"type":"number"},"netChange":{"type":"number"},"percentageChange":{"type":"number"},"categoryBreakdown":{"type":"object","properties":{"network":{"type":"object","properties":{"added":{"type":"number"},"removed":{"type":"number"}},"required":["added","removed"]},"cosmetic":{"type":"object","properties":{"added":{"type":"number"},"removed":{"type":"number"}},"required":["added","removed"]},"host":{"type":"object","properties":{"added":{"type":"number"},"removed":{"type":"number"}},"required":["added","removed"]},"comment":{"type":"object","properties":{"added":{"type":"number"},"removed":{"type":"number"}},"required":["added","removed"]},"unknown":{"type":"object","properties":{"added":{"type":"number"},"removed":{"type":"number"}},"required":["added","removed"]}},"required":["network","cosmetic","host","comment","unknown"]}},"required":["originalCount","newCount","addedCount","removedCount","unchangedCount","netChange","percentageChange"]},"added":{"type":"array","items":{"type":"object","properties":{"rule":{"type":"string"},"type":{"type":"string","enum":["added","removed","modified"]},"source":{"type":"string"},"originalLine":{"type":"number"},"newLine":{"type":"number"},"category":{"type":"string","enum":["network","cosmetic","host","comment","unknown"]},"syntax":{"type":"string"},"isException":{"type":"boolean"}},"required":["rule","type"]}},"removed":{"type":"array","items":{"type":"object","properties":{"rule":{"type":"string"},"type":{"type":"string","enum":["added","removed","modified"]},"source":{"type":"string"},"originalLine":{"type":"number"},"newLine":{"type":"number"},"category":{"type":"string","enum":["network","cosmetic","host","comment","unknown"]},"syntax":{"type":"string"},"isException":{"type":"boolean"}},"required":["rule","type"]}},"domainChanges":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string"},"added":{"type":"number"},"removed":{"type":"number"}},"required":["domain","added","removed"]}}},"required":["timestamp","generatorVersion","original","current","summary","added","removed","domainChanges"]},"duration":{"type":"string"}},"required":["success","parseErrors","report","duration"]}}}},"400":{"description":"Invalid JSON body","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["success","error"]}}}},"422":{"description":"Request validation failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/compile/async":{"post":{"tags":["Compile"],"summary":"Async compile","description":"Queues a compilation job for asynchronous processing","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"configuration":{"type":"object","additionalProperties":{"nullable":true}},"preFetchedContent":{"type":"object","additionalProperties":{"type":"string"}},"benchmark":{"type":"boolean"},"priority":{"type":"string","enum":["low","normal","high"]},"turnstileToken":{"type":"string"}},"required":["configuration"]}}}},"responses":{"202":{"description":"Job queued successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"jobId":{"type":"string"},"status":{"type":"string"}},"required":["success","jobId","status"]}}}}}}},"/api/compile/batch/async":{"post":{"tags":["Compile"],"summary":"Async batch compile","description":"Queues multiple compilation jobs for asynchronous processing","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"requests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"configuration":{"type":"object","additionalProperties":{"nullable":true}},"preFetchedContent":{"type":"object","additionalProperties":{"type":"string"}},"benchmark":{"type":"boolean"}},"required":["id","configuration"]}},"priority":{"type":"string","enum":["low","normal","high"]},"turnstileToken":{"type":"string"}},"required":["requests"]}}}},"responses":{"202":{"description":"Batch jobs queued","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"batchId":{"type":"string"},"jobIds":{"type":"array","items":{"type":"string"}}},"required":["success","batchId","jobIds"]}}}}}}},"/api/compile/container":{"post":{"tags":["Compile"],"summary":"Container compile","description":"Compiles filter lists using Durable Object container","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"configuration":{"type":"object","additionalProperties":{"nullable":true}},"preFetchedContent":{"type":"object","additionalProperties":{"type":"string"}},"benchmark":{"type":"boolean"},"priority":{"type":"string","enum":["low","normal","high"]},"turnstileToken":{"type":"string"}},"required":["configuration"]}}}},"responses":{"200":{"description":"Compilation successful","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"result":{"type":"object","properties":{"output":{"type":"string"},"stats":{"type":"object","properties":{"total":{"type":"number"},"processed":{"type":"number"},"failed":{"type":"number"}},"required":["total","processed","failed"]},"benchmark":{"type":"object","additionalProperties":{"nullable":true}}},"required":["output"]}},"required":["success","result"]}}}},"503":{"description":"Container not available","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/convert-rule":{"post":{"tags":["Compile"],"summary":"Convert a filter rule to a different syntax","description":"Converts a single adblock filter rule between AdGuard and uBlock Origin syntaxes using AGTree","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"rule":{"type":"string","minLength":1},"targetSyntax":{"type":"string","enum":["adg","ubo"]},"turnstileToken":{"type":"string"}},"required":["rule","targetSyntax"]}}}},"responses":{"200":{"description":"Conversion result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"rule":{"type":"string"},"targetSyntax":{"type":"string","enum":["adg","ubo"]},"convertedRules":{"type":"array","items":{"type":"string"}},"isConverted":{"type":"boolean"},"error":{"type":"string"},"duration":{"type":"string"}},"required":["success","rule","targetSyntax","convertedRules","isConverted","duration"]}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/rules":{"get":{"tags":["Rules"],"summary":"List saved rule sets","description":"Returns all saved rule sets for the authenticated user","responses":{"200":{"description":"List of rule sets","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"rules":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the rule set"},"name":{"type":"string"},"description":{"type":"string"},"rules":{"type":"array","items":{"type":"string"}},"ruleCount":{"type":"integer","minimum":0},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 last-updated timestamp"}},"required":["id","name","rules","ruleCount","createdAt","updatedAt"]}}},"required":["success","rules"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}},"post":{"tags":["Rules"],"summary":"Create a new rule set","description":"Creates a new saved rule set for the authenticated user","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128,"description":"Human-readable name for this rule set"},"description":{"type":"string","maxLength":512,"description":"Optional description"},"rules":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":10000},"tags":{"type":"array","items":{"type":"string","maxLength":64},"maxItems":20,"description":"Optional tags for categorisation"}},"required":["name","rules"]}}}},"responses":{"201":{"description":"Rule set created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"ruleSet":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the rule set"},"name":{"type":"string"},"description":{"type":"string"},"rules":{"type":"array","items":{"type":"string"}},"ruleCount":{"type":"integer","minimum":0},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 last-updated timestamp"}},"required":["id","name","rules","ruleCount","createdAt","updatedAt"]}},"required":["success","ruleSet"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/rules/{id}":{"get":{"tags":["Rules"],"summary":"Get a rule set by ID","description":"Returns a single saved rule set by its ID","parameters":[{"schema":{"type":"string","format":"uuid","description":"Rule set ID"},"required":true,"description":"Rule set ID","name":"id","in":"path"}],"responses":{"200":{"description":"Rule set found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"ruleSet":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the rule set"},"name":{"type":"string"},"description":{"type":"string"},"rules":{"type":"array","items":{"type":"string"}},"ruleCount":{"type":"integer","minimum":0},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 last-updated timestamp"}},"required":["id","name","rules","ruleCount","createdAt","updatedAt"]}},"required":["success","ruleSet"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"Rule set not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}},"put":{"tags":["Rules"],"summary":"Update a rule set","description":"Updates an existing saved rule set","parameters":[{"schema":{"type":"string","format":"uuid","description":"Rule set ID"},"required":true,"description":"Rule set ID","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128},"description":{"type":"string","maxLength":512},"rules":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":10000},"tags":{"type":"array","items":{"type":"string","maxLength":64},"maxItems":20}}}}}},"responses":{"200":{"description":"Rule set updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"ruleSet":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the rule set"},"name":{"type":"string"},"description":{"type":"string"},"rules":{"type":"array","items":{"type":"string"}},"ruleCount":{"type":"integer","minimum":0},"tags":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 last-updated timestamp"}},"required":["id","name","rules","ruleCount","createdAt","updatedAt"]}},"required":["success","ruleSet"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"Rule set not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}},"delete":{"tags":["Rules"],"summary":"Delete a rule set","description":"Deletes a saved rule set by its ID","parameters":[{"schema":{"type":"string","format":"uuid","description":"Rule set ID"},"required":true,"description":"Rule set ID","name":"id","in":"path"}],"responses":{"200":{"description":"Rule set deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}},"required":["success","message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"Rule set not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/queue/stats":{"get":{"tags":["Queue"],"summary":"Get queue statistics","description":"Returns current queue statistics including pending, completed, failed, and cancelled job counts","responses":{"200":{"description":"Queue statistics","content":{"application/json":{"schema":{"type":"object","properties":{"pending":{"type":"integer","minimum":0,"description":"Number of pending jobs"},"completed":{"type":"integer","minimum":0,"description":"Number of completed jobs"},"failed":{"type":"integer","minimum":0,"description":"Number of failed jobs"},"cancelled":{"type":"integer","minimum":0,"description":"Number of cancelled jobs"},"totalProcessingTime":{"type":"number","minimum":0,"description":"Total processing time in milliseconds"},"averageProcessingTime":{"type":"number","minimum":0,"description":"Average processing time in milliseconds"},"processingRate":{"type":"number","minimum":0,"description":"Jobs processed per second"},"queueLag":{"type":"number","minimum":0,"description":"Current queue lag in milliseconds"},"lastUpdate":{"type":"string","format":"date-time","description":"ISO 8601 timestamp of last stats update"},"history":{"type":"array","items":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique job request identifier"},"status":{"type":"string","enum":["pending","completed","failed","cancelled"],"description":"Job status"},"enqueuedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when job was enqueued"},"completedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when job completed"},"processingTime":{"type":"number","description":"Processing time in milliseconds"},"error":{"type":"string","description":"Error message if job failed"}},"required":["requestId","status","enqueuedAt"]},"description":"Recent job history"},"depthHistory":{"type":"array","items":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"depth":{"type":"integer","minimum":0,"description":"Queue depth at this time"}},"required":["timestamp","depth"]},"description":"Queue depth over time"}},"required":["pending","completed","failed","cancelled","totalProcessingTime","averageProcessingTime","processingRate","queueLag","lastUpdate","history","depthHistory"]}}}}}}},"/api/queue/history":{"get":{"tags":["Queue"],"summary":"Get queue history","description":"Returns recent job history and queue depth history","responses":{"200":{"description":"Queue history","content":{"application/json":{"schema":{"type":"object","properties":{"history":{"type":"array","items":{"type":"object","properties":{"requestId":{"type":"string","description":"Unique job request identifier"},"status":{"type":"string","enum":["pending","completed","failed","cancelled"],"description":"Job status"},"enqueuedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when job was enqueued"},"completedAt":{"type":"string","format":"date-time","description":"ISO 8601 timestamp when job completed"},"processingTime":{"type":"number","description":"Processing time in milliseconds"},"error":{"type":"string","description":"Error message if job failed"}},"required":["requestId","status","enqueuedAt"]}},"depthHistory":{"type":"array","items":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp"},"depth":{"type":"integer","minimum":0,"description":"Queue depth at this time"}},"required":["timestamp","depth"]}}},"required":["history","depthHistory"]}}}}}}},"/api/queue/results/{requestId}":{"get":{"tags":["Queue"],"summary":"Get queue job results","description":"Returns the results of a specific queue job by request ID","parameters":[{"schema":{"type":"string","description":"Request ID of the queue job"},"required":true,"description":"Request ID of the queue job","name":"requestId","in":"path"}],"responses":{"200":{"description":"Job results or not found status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"},"status":{"type":"string"},"result":{"nullable":true}},"required":["success"]}}}},"400":{"description":"Invalid request ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/queue/cancel/{requestId}":{"delete":{"tags":["Queue"],"summary":"Cancel a queue job","description":"Attempts to cancel a pending queue job. This is a best-effort operation - the job may have already started processing.","parameters":[{"schema":{"type":"string","pattern":"^[a-zA-Z0-9_-]+$","description":"Request ID of the queue job to cancel"},"required":true,"description":"Request ID of the queue job to cancel","name":"requestId","in":"path"}],"responses":{"200":{"description":"Cancellation signal sent","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}},"required":["success","message"]}}}},"400":{"description":"Invalid request ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/configuration/defaults":{"get":{"tags":["Configuration"],"summary":"Get default configuration values","description":"Returns system defaults and hard limits for compilation","responses":{"200":{"description":"Default configuration values","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"defaults":{"type":"object","properties":{"compilation":{"type":"object","additionalProperties":{"nullable":true}},"validation":{"type":"object","additionalProperties":{"nullable":true}}},"required":["compilation","validation"]},"limits":{"type":"object","additionalProperties":{"nullable":true}}},"required":["success","defaults"]}}}}}}},"/api/configuration/validate":{"post":{"tags":["Configuration"],"summary":"Validate configuration object","description":"Validates a configuration object against the schema","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"config":{"type":"object","additionalProperties":{"nullable":true}},"turnstileToken":{"type":"string"}},"required":["config"]}}}},"responses":{"200":{"description":"Configuration is valid","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"nullable":true}}},"required":["success","valid"]}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/configuration/resolve":{"post":{"tags":["Configuration"],"summary":"Resolve configuration layers","description":"Merges configuration layers and returns the effective configuration","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"config":{"type":"object","additionalProperties":{"nullable":true}},"override":{"type":"object","additionalProperties":{"nullable":true}},"applyEnvOverrides":{"type":"boolean"},"turnstileToken":{"type":"string"}},"required":["config"]}}}},"responses":{"200":{"description":"Resolved configuration","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"config":{"type":"object","additionalProperties":{"nullable":true}}},"required":["success","config"]}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/configuration/create":{"post":{"tags":["Configuration"],"summary":"Create and store configuration","description":"Creates and stores a configuration file, returning an ID for download","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"config":{"type":"object","additionalProperties":{"nullable":true}},"format":{"type":"string","enum":["json","yaml"]},"turnstileToken":{"type":"string"}},"required":["config"]}}}},"responses":{"200":{"description":"Configuration created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"id":{"type":"string"},"format":{"type":"string"},"expiresIn":{"type":"number"},"valid":{"type":"boolean"},"errors":{"type":"array","items":{"nullable":true}}},"required":["success"]}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Turnstile verification failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/configuration/download/:id":{"get":{"tags":["Configuration"],"summary":"Download stored configuration","description":"Downloads a previously stored configuration file","parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["json","yaml"]},"required":false,"name":"format","in":"query"}],"responses":{"200":{"description":"Configuration file","content":{"application/json":{"schema":{"nullable":true}},"application/x-yaml":{"schema":{"nullable":true}}}},"404":{"description":"Configuration not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/configuration/saved":{"get":{"tags":["Configuration"],"summary":"List saved configurations","description":"Returns up to 50 saved configurations for the authenticated user, ordered by most recently updated.","responses":{"200":{"description":"List of saved configurations","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"configs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier"},"name":{"type":"string","description":"Human-readable name"},"description":{"type":"string","nullable":true,"description":"Optional description"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 last-updated timestamp"}},"required":["id","name","description","createdAt","updatedAt"]}},"total":{"type":"integer","minimum":0}},"required":["success","configs","total"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden — requires an interactive user session","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}},"post":{"tags":["Configuration"],"summary":"Save a configuration","description":"Persists a configuration to the authenticated user's account.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128,"description":"Human-readable name"},"description":{"type":"string","maxLength":512,"description":"Optional description"},"config":{"type":"object","additionalProperties":{"nullable":true},"description":"Configuration object to persist"}},"required":["name","config"]}}}},"responses":{"201":{"description":"Configuration saved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"config":{"type":"object","additionalProperties":{"nullable":true}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["success","id","name","description","config","createdAt","updatedAt"]}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden — requires an interactive user session","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/configuration/saved/{id}":{"delete":{"tags":["Configuration"],"summary":"Delete a saved configuration","description":"Permanently deletes a saved configuration owned by the authenticated user.","parameters":[{"schema":{"type":"string","format":"uuid","description":"Saved configuration ID"},"required":true,"description":"Saved configuration ID","name":"id","in":"path"}],"responses":{"204":{"description":"Configuration deleted"},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden — requires an interactive user session","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"Configuration not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/auth/config":{"get":{"tags":["Admin"],"summary":"Get auth configuration","description":"Returns a read-only view of the authentication configuration at runtime, including active provider, social providers, MFA status, session settings, tiers, and route permissions. Admin tier and admin role required.","responses":{"200":{"description":"Auth configuration","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"provider":{"type":"string","enum":["better-auth"]},"socialProviders":{"type":"object","properties":{"github":{"type":"object","properties":{"configured":{"type":"boolean"}},"required":["configured"]},"google":{"type":"object","properties":{"configured":{"type":"boolean"}},"required":["configured"]}},"required":["github","google"]},"mfa":{"type":"object","properties":{"enabled":{"type":"boolean"}},"required":["enabled"]},"session":{"type":"object","properties":{"expiresIn":{"type":"number"},"updateAge":{"type":"number"},"cookieCacheMaxAge":{"type":"number"}},"required":["expiresIn","updateAge","cookieCacheMaxAge"]},"betterAuth":{"type":"object","properties":{"secretConfigured":{"type":"boolean"},"baseUrl":{"type":"string","nullable":true}},"required":["secretConfigured","baseUrl"]},"tiers":{"type":"array","items":{"type":"object","properties":{"tier":{"type":"string"},"displayName":{"type":"string"},"order":{"type":"number"},"rateLimit":{"type":"number","nullable":true},"description":{"type":"string"}},"required":["tier","displayName","order","rateLimit","description"]}},"routes":{"type":"array","items":{"type":"object","properties":{"pattern":{"type":"string"},"minTier":{"type":"string"},"requiredRole":{"type":"string","nullable":true},"description":{"type":"string"}},"required":["pattern","minTier","requiredRole","description"]}}},"required":["success","provider","socialProviders","mfa","session","betterAuth","tiers","routes"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/users":{"get":{"tags":["Admin"],"summary":"List all users","description":"Returns all Better Auth users, paginated and optionally filtered by tier, role, or search query. Admin tier and admin role required.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"description":"Maximum number of results per page"},"required":false,"description":"Maximum number of results per page","name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0,"description":"Number of results to skip"},"required":false,"description":"Number of results to skip","name":"offset","in":"query"},{"schema":{"type":"string","description":"Filter by user tier"},"required":false,"description":"Filter by user tier","name":"tier","in":"query"},{"schema":{"type":"string","description":"Filter by user role"},"required":false,"description":"Filter by user role","name":"role","in":"query"},{"schema":{"type":"string","description":"Search by email or name (substring match)"},"required":false,"description":"Search by email or name (substring match)","name":"search","in":"query"}],"responses":{"200":{"description":"List of users","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"users":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"emailVerified":{"type":"boolean"},"image":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"tier":{"type":"string","enum":["anonymous","free","pro","admin"]},"role":{"type":"string"},"banned":{"type":"boolean"},"banReason":{"type":"string","nullable":true},"banExpires":{"type":"string","nullable":true,"format":"date-time"}},"required":["id","name","email","emailVerified","image","createdAt","updatedAt"]}},"total":{"type":"integer","minimum":0},"limit":{"type":"integer","minimum":0,"exclusiveMinimum":true},"offset":{"type":"integer","minimum":0}},"required":["success","users","total","limit","offset"]}}}},"400":{"description":"Invalid pagination or filter params","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/users/{id}":{"get":{"tags":["Admin"],"summary":"Get a single user by ID","description":"Returns a single Better Auth user by their ID. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"User ID"},"required":true,"description":"User ID","name":"id","in":"path"}],"responses":{"200":{"description":"User found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"user":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"emailVerified":{"type":"boolean"},"image":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"tier":{"type":"string","enum":["anonymous","free","pro","admin"]},"role":{"type":"string"},"banned":{"type":"boolean"},"banReason":{"type":"string","nullable":true},"banExpires":{"type":"string","nullable":true,"format":"date-time"}},"required":["id","name","email","emailVerified","image","createdAt","updatedAt"]}},"required":["success","user"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}},"patch":{"tags":["Admin"],"summary":"Update a user","description":"Updates a user's tier and/or role. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"User ID"},"required":true,"description":"User ID","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"tier":{"type":"string","enum":["anonymous","free","pro","admin"],"description":"Updated user tier"},"role":{"type":"string","minLength":1,"maxLength":64,"description":"Updated user role"}}}}}},"responses":{"200":{"description":"User updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"user":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"emailVerified":{"type":"boolean"},"image":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"tier":{"type":"string","enum":["anonymous","free","pro","admin"]},"role":{"type":"string"},"banned":{"type":"boolean"},"banReason":{"type":"string","nullable":true},"banExpires":{"type":"string","nullable":true,"format":"date-time"}},"required":["id","name","email","emailVerified","image","createdAt","updatedAt"]}},"required":["success","user"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a user","description":"Deletes a user and all their sessions. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"User ID"},"required":true,"description":"User ID","name":"id","in":"path"}],"responses":{"200":{"description":"User deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}},"required":["success","message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/users/{id}/ban":{"post":{"tags":["Admin"],"summary":"Ban a user","description":"Bans a user with an optional reason and expiration date. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"User ID"},"required":true,"description":"User ID","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string","maxLength":500,"description":"Reason for banning"},"expires":{"type":"string","format":"date-time","description":"ISO 8601 expiration timestamp"}}}}}},"responses":{"200":{"description":"User banned successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}},"required":["success","message"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/users/{id}/unban":{"post":{"tags":["Admin"],"summary":"Unban a user","description":"Unbans a previously banned user. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"User ID"},"required":true,"description":"User ID","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"User unbanned successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}},"required":["success","message"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"User not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/users/{id}/sessions":{"delete":{"tags":["Admin"],"summary":"Revoke all user sessions","description":"Revokes all active sessions for a specific user. Admin tier and admin role required. Also requires Cloudflare Access JWT verification for defense-in-depth.","parameters":[{"schema":{"type":"string","description":"User ID"},"required":true,"description":"User ID","name":"id","in":"path"}],"responses":{"200":{"description":"Sessions revoked successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}},"required":["success","message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role and Cloudflare Access JWT","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/usage/{userId}":{"get":{"tags":["Admin"],"summary":"Get user API usage statistics","description":"Returns per-user API usage statistics from KV storage for a specified lookback period. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"User ID to get usage for"},"required":true,"description":"User ID to get usage for","name":"userId","in":"path"},{"schema":{"type":"integer","nullable":true,"default":30,"description":"Number of days to look back for usage stats"},"required":false,"description":"Number of days to look back for usage stats","name":"days","in":"query"}],"responses":{"200":{"description":"User usage statistics","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"userId":{"type":"string"},"total":{"type":"object","nullable":true,"properties":{"count":{"type":"integer","minimum":0},"firstSeen":{"type":"string","format":"date-time"},"lastSeen":{"type":"string","format":"date-time"}},"required":["count","firstSeen","lastSeen"]},"days":{"type":"array","items":{"type":"object","properties":{"date":{"type":"string"},"count":{"type":"integer","minimum":0},"routes":{"type":"object","additionalProperties":{"type":"number"}}},"required":["date","count","routes"]}},"lookbackDays":{"type":"integer","minimum":0,"exclusiveMinimum":true}},"required":["success","userId","total","days","lookbackDays"]}}}},"400":{"description":"Invalid days parameter","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/storage/stats":{"get":{"tags":["Admin"],"summary":"Get storage statistics","description":"Returns statistics about storage entries, filter cache, compilation metadata, and expired entries. Admin tier and admin role required.","responses":{"200":{"description":"Storage statistics","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"stats":{"type":"object","properties":{"storage_entries":{"type":"integer","minimum":0},"filter_cache":{"type":"integer","minimum":0},"compilation_metadata":{"type":"integer","minimum":0},"expired_storage":{"type":"integer","minimum":0},"expired_cache":{"type":"integer","minimum":0}},"required":["storage_entries","filter_cache","compilation_metadata","expired_storage","expired_cache"]},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp of stats snapshot"}},"required":["success","stats","timestamp"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role and Cloudflare Access JWT","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/storage/clear-expired":{"post":{"tags":["Admin"],"summary":"Clear expired storage entries","description":"Deletes all expired storage entries and filter cache entries. Admin tier and admin role required.","responses":{"200":{"description":"Expired entries cleared successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"deleted":{"type":"integer","minimum":0},"message":{"type":"string"}},"required":["success","deleted","message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role and Cloudflare Access JWT","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/storage/clear-cache":{"post":{"tags":["Admin"],"summary":"Clear all cache entries","description":"Deletes all filter cache entries and cache-related storage entries. Admin tier and admin role required.","responses":{"200":{"description":"Cache entries cleared successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"deleted":{"type":"integer","minimum":0},"message":{"type":"string"}},"required":["success","deleted","message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role and Cloudflare Access JWT","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/storage/export":{"get":{"tags":["Admin"],"summary":"Export storage data","description":"Exports storage entries, filter cache, and compilation metadata as JSON. Limited to 1000 storage entries, 100 filter cache entries, and 100 compilation metadata entries. Admin tier and admin role required.","responses":{"200":{"description":"Storage data exported successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"exportedAt":{"type":"string","format":"date-time"},"storage_entries":{"type":"array","items":{"nullable":true}},"filter_cache":{"type":"array","items":{"nullable":true}},"compilation_metadata":{"type":"array","items":{"nullable":true}}},"required":["success","exportedAt","storage_entries","filter_cache","compilation_metadata"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role and Cloudflare Access JWT","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/storage/vacuum":{"post":{"tags":["Admin"],"summary":"Vacuum D1 database","description":"Runs VACUUM on the D1 database to reclaim storage space. Admin tier and admin role required.","responses":{"200":{"description":"Database vacuum completed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}},"required":["success","message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role and Cloudflare Access JWT","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"D1 database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/storage/tables":{"get":{"tags":["Admin"],"summary":"List database tables","description":"Returns a list of all tables and indexes in the D1 database. Admin tier and admin role required.","responses":{"200":{"description":"List of tables and indexes","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"tables":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string"}},"required":["name","type"]}}},"required":["success","tables"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role and Cloudflare Access JWT","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"D1 database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/storage/query":{"post":{"tags":["Admin"],"summary":"Execute read-only SQL query","description":"Executes a read-only SELECT query against the D1 database. Only SELECT queries are allowed, with a maximum of 1000 rows. Admin tier and admin role required.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"sql":{"type":"string","minLength":1,"description":"SQL query to execute (SELECT only)"}},"required":["sql"]}}}},"responses":{"200":{"description":"Query executed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"rows":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"rowCount":{"type":"integer","minimum":0},"meta":{"nullable":true}},"required":["success","rows","rowCount"]}}}},"400":{"description":"Invalid query or validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role and Cloudflare Access JWT","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"D1 database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/neon/project":{"get":{"tags":["Admin"],"summary":"Get Neon project overview","description":"Returns Neon project information. Requires projectId as query parameter or NEON_PROJECT_ID env variable. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"Neon project ID (overrides NEON_PROJECT_ID env)"},"required":false,"description":"Neon project ID (overrides NEON_PROJECT_ID env)","name":"projectId","in":"query"}],"responses":{"200":{"description":"Neon project information","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"project":{"nullable":true,"description":"Neon project object from Neon API"}},"required":["success"]}}}},"400":{"description":"Missing project ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"NEON_API_KEY not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/neon/branches":{"get":{"tags":["Admin"],"summary":"List Neon branches","description":"Returns all branches for a Neon project. Requires projectId as query parameter or NEON_PROJECT_ID env variable. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"Neon project ID (overrides NEON_PROJECT_ID env)"},"required":false,"description":"Neon project ID (overrides NEON_PROJECT_ID env)","name":"projectId","in":"query"}],"responses":{"200":{"description":"List of Neon branches","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"branches":{"type":"array","items":{"nullable":true},"description":"Array of Neon branch objects"}},"required":["success","branches"]}}}},"400":{"description":"Missing project ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"NEON_API_KEY not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}},"post":{"tags":["Admin"],"summary":"Create a Neon branch","description":"Creates a new Neon branch. Requires projectId as query parameter or NEON_PROJECT_ID env variable. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"Neon project ID (overrides NEON_PROJECT_ID env)"},"required":false,"description":"Neon project ID (overrides NEON_PROJECT_ID env)","name":"projectId","in":"query"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":128,"description":"Optional branch name (auto-generated if omitted)"},"parent_id":{"type":"string","maxLength":128,"description":"Parent branch ID to fork from (defaults to primary branch)"}}}}}},"responses":{"201":{"description":"Branch created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"],"additionalProperties":{"nullable":true}}}}},"400":{"description":"Validation error or missing project ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"NEON_API_KEY not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/neon/branches/{branchId}":{"get":{"tags":["Admin"],"summary":"Get Neon branch details","description":"Returns detailed information about a specific Neon branch. Requires projectId as query parameter or NEON_PROJECT_ID env variable. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"Neon branch ID"},"required":true,"description":"Neon branch ID","name":"branchId","in":"path"},{"schema":{"type":"string","description":"Neon project ID (overrides NEON_PROJECT_ID env)"},"required":false,"description":"Neon project ID (overrides NEON_PROJECT_ID env)","name":"projectId","in":"query"}],"responses":{"200":{"description":"Neon branch details","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"branch":{"nullable":true,"description":"Neon branch object from Neon API"}},"required":["success"]}}}},"400":{"description":"Missing project ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"Branch not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"NEON_API_KEY not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a Neon branch","description":"Deletes a Neon branch. Requires projectId as query parameter or NEON_PROJECT_ID env variable. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"Neon branch ID"},"required":true,"description":"Neon branch ID","name":"branchId","in":"path"},{"schema":{"type":"string","description":"Neon project ID (overrides NEON_PROJECT_ID env)"},"required":false,"description":"Neon project ID (overrides NEON_PROJECT_ID env)","name":"projectId","in":"query"}],"responses":{"200":{"description":"Branch deleted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"],"additionalProperties":{"nullable":true}}}}},"400":{"description":"Missing project ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"Branch not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"NEON_API_KEY not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/neon/endpoints":{"get":{"tags":["Admin"],"summary":"List Neon compute endpoints","description":"Returns all compute endpoints for a Neon project. Requires projectId as query parameter or NEON_PROJECT_ID env variable. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"Neon project ID (overrides NEON_PROJECT_ID env)"},"required":false,"description":"Neon project ID (overrides NEON_PROJECT_ID env)","name":"projectId","in":"query"}],"responses":{"200":{"description":"List of Neon endpoints","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"endpoints":{"type":"array","items":{"nullable":true},"description":"Array of Neon compute endpoint objects"}},"required":["success","endpoints"]}}}},"400":{"description":"Missing project ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"NEON_API_KEY not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/neon/databases/{branchId}":{"get":{"tags":["Admin"],"summary":"List databases for a branch","description":"Returns all databases for a specific Neon branch. Requires projectId as query parameter or NEON_PROJECT_ID env variable. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","description":"Neon branch ID"},"required":true,"description":"Neon branch ID","name":"branchId","in":"path"},{"schema":{"type":"string","description":"Neon project ID (overrides NEON_PROJECT_ID env)"},"required":false,"description":"Neon project ID (overrides NEON_PROJECT_ID env)","name":"projectId","in":"query"}],"responses":{"200":{"description":"List of databases for the branch","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"databases":{"type":"array","items":{"nullable":true},"description":"Array of database objects for the branch"}},"required":["success","databases"]}}}},"400":{"description":"Missing project ID","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"NEON_API_KEY not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/neon/query":{"post":{"tags":["Admin"],"summary":"Execute SQL query via Neon serverless driver","description":"Executes a SQL query against a Neon database using the serverless driver. Admin tier and admin role required.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"connectionString":{"type":"string","minLength":1,"description":"Full postgres:// connection string"},"sql":{"type":"string","minLength":1,"description":"SQL statement to execute"},"params":{"type":"array","items":{"nullable":true},"description":"Optional positional parameters ($1, $2, ...)"}},"required":["connectionString","sql"]}}}},"responses":{"200":{"description":"Query executed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"rows":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"rowCount":{"type":"integer","minimum":0},"duration":{"type":"string"}},"required":["success","rows","rowCount","duration"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"NEON_API_KEY not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/agents/sessions":{"get":{"tags":["Admin"],"summary":"List agent sessions","description":"Returns all agent sessions, paginated and sorted by most recent first. Admin tier and admin role required.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"description":"Maximum number of results per page"},"required":false,"description":"Maximum number of results per page","name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0,"description":"Number of results to skip"},"required":false,"description":"Number of results to skip","name":"offset","in":"query"}],"responses":{"200":{"description":"List of agent sessions","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string"},"providerType":{"type":"string"},"providerId":{"type":"string","nullable":true},"sessionName":{"type":"string"},"startedAt":{"type":"string","format":"date-time"},"endedAt":{"type":"string","nullable":true,"format":"date-time"},"endReason":{"type":"string","nullable":true},"totalInvocations":{"type":"integer","minimum":0},"totalInputTokens":{"type":"integer","minimum":0},"totalOutputTokens":{"type":"integer","minimum":0},"estimatedCostUsd":{"type":"number","minimum":0}},"required":["id","userId","providerType","providerId","sessionName","startedAt","endedAt","endReason","totalInvocations","totalInputTokens","totalOutputTokens","estimatedCostUsd"],"additionalProperties":{"nullable":true}}},"total":{"type":"integer","minimum":0},"limit":{"type":"integer","minimum":0,"exclusiveMinimum":true},"offset":{"type":"integer","minimum":0}},"required":["success","items","total","limit","offset"]}}}},"400":{"description":"Invalid pagination params","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/agents/sessions/{sessionId}":{"get":{"tags":["Admin"],"summary":"Get agent session details","description":"Returns a single agent session by ID, including all its invocations. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","format":"uuid","description":"Agent session ID"},"required":true,"description":"Agent session ID","name":"sessionId","in":"path"}],"responses":{"200":{"description":"Agent session with invocations","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"id":{"type":"string","format":"uuid"},"userId":{"type":"string"},"providerType":{"type":"string"},"providerId":{"type":"string","nullable":true},"sessionName":{"type":"string"},"startedAt":{"type":"string","format":"date-time"},"endedAt":{"type":"string","nullable":true,"format":"date-time"},"endReason":{"type":"string","nullable":true},"totalInvocations":{"type":"integer","minimum":0},"totalInputTokens":{"type":"integer","minimum":0},"totalOutputTokens":{"type":"integer","minimum":0},"estimatedCostUsd":{"type":"number","minimum":0},"invocations":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"sessionId":{"type":"string","format":"uuid"},"invokedAt":{"type":"string","format":"date-time"},"modelUsed":{"type":"string"},"inputTokens":{"type":"integer","minimum":0},"outputTokens":{"type":"integer","minimum":0},"costUsd":{"type":"number","minimum":0},"durationMs":{"type":"integer","nullable":true,"minimum":0}},"required":["id","sessionId","invokedAt","modelUsed","inputTokens","outputTokens","costUsd","durationMs"],"additionalProperties":{"nullable":true}}}},"required":["success","id","userId","providerType","providerId","sessionName","startedAt","endedAt","endReason","totalInvocations","totalInputTokens","totalOutputTokens","estimatedCostUsd","invocations"],"additionalProperties":{"nullable":true}}}}},"400":{"description":"Invalid session ID format","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"Agent session not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}},"delete":{"tags":["Admin"],"summary":"Terminate an agent session","description":"Terminates an active agent session. Returns 409 if the session is already ended. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","format":"uuid","description":"Agent session ID"},"required":true,"description":"Agent session ID","name":"sessionId","in":"path"}],"responses":{"200":{"description":"Agent session terminated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}},"required":["success","message"]}}}},"400":{"description":"Invalid session ID format","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"Agent session not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"409":{"description":"Session already ended","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/agents/audit":{"get":{"tags":["Admin"],"summary":"List agent audit log","description":"Returns all agent audit log entries, paginated and sorted by most recent first. Admin tier and admin role required.","parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50,"description":"Maximum number of results per page"},"required":false,"description":"Maximum number of results per page","name":"limit","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0,"description":"Number of results to skip"},"required":false,"description":"Number of results to skip","name":"offset","in":"query"}],"responses":{"200":{"description":"List of audit log entries","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"userId":{"type":"string"},"sessionId":{"type":"string","nullable":true,"format":"uuid"},"action":{"type":"string"},"details":{"nullable":true},"createdAt":{"type":"string","format":"date-time"}},"required":["id","userId","sessionId","action","createdAt"],"additionalProperties":{"nullable":true}}},"total":{"type":"integer","minimum":0},"limit":{"type":"integer","minimum":0,"exclusiveMinimum":true},"offset":{"type":"integer","minimum":0}},"required":["success","items","total","limit","offset"]}}}},"400":{"description":"Invalid pagination params","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires admin role","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/admin/security/overview":{"get":{"tags":["Admin"],"summary":"Security Overview","description":"Returns aggregated security event metrics from the admin audit log. Surfaces denied/failed entries by action and resource type. Also reports which event types are actively tracked in Analytics Engine. Admin tier and admin role required.","parameters":[{"schema":{"type":"string","enum":["24h","7d","30d"],"default":"24h","description":"Time window for aggregation"},"required":false,"description":"Time window for aggregation","name":"window","in":"query"}],"responses":{"200":{"description":"Security overview metrics","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[true]},"timestamp":{"type":"string","format":"date-time"},"window":{"type":"string","enum":["24h","7d","30d"]},"total_security_events":{"type":"integer","minimum":0},"by_status":{"type":"object","properties":{"denied":{"type":"integer","minimum":0},"failure":{"type":"integer","minimum":0}},"required":["denied","failure"]},"by_action":{"type":"array","items":{"type":"object","properties":{"event_type":{"type":"string"},"count":{"type":"integer","minimum":0}},"required":["event_type","count"]}},"by_resource_type":{"type":"array","items":{"type":"object","properties":{"resource_type":{"type":"string"},"count":{"type":"integer","minimum":0}},"required":["resource_type","count"]}},"recent_events":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer"},"actor_id":{"type":"string"},"action":{"type":"string"},"resource_type":{"type":"string"},"resource_id":{"type":"string","nullable":true},"status":{"type":"string","enum":["failure","denied"]},"ip_address":{"type":"string","nullable":true},"created_at":{"type":"string"}},"required":["id","actor_id","action","resource_type","resource_id","status","ip_address","created_at"]}},"analytics_engine_tracked_events":{"type":"array","items":{"type":"string"}},"analytics_engine_configured":{"type":"boolean"}},"required":["success","timestamp","window","total_security_events","by_status","by_action","by_resource_type","recent_events","analytics_engine_tracked_events","analytics_engine_configured"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden — admin role required","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/metrics/prometheus":{"get":{"tags":["Monitoring"],"summary":"Get Prometheus metrics","description":"Returns metrics in Prometheus text format for scraping","responses":{"200":{"description":"Prometheus metrics in text format","content":{"text/plain; version=0.0.4; charset=utf-8":{"schema":{"type":"string"}}}},"403":{"description":"Forbidden - Cloudflare Access denied","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/metrics":{"get":{"tags":["Monitoring"],"summary":"Get application metrics","description":"Returns application metrics in JSON format","responses":{"200":{"description":"Application metrics","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"window":{"type":"string"},"timestamp":{"type":"string"},"endpoints":{"type":"object","additionalProperties":{"type":"object","properties":{"count":{"type":"number"},"success":{"type":"number"},"failed":{"type":"number"},"avgDuration":{"type":"number"},"errors":{"type":"object","additionalProperties":{"type":"number"}}},"required":["count","success","failed","avgDuration","errors"]}}},"required":["success","window","timestamp","endpoints"]}}}}}}},"/api/health":{"get":{"tags":["Health"],"summary":"Health check endpoint","description":"Returns the health status of the application and its dependencies","responses":{"200":{"description":"Service is healthy","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"status":{"type":"string"},"timestamp":{"type":"string"},"checks":{"type":"object","additionalProperties":{"nullable":true}}},"required":["success","status","timestamp"]}}}},"503":{"description":"Service is unhealthy","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"status":{"type":"string"},"error":{"type":"string"}},"required":["success","status"]}}}}}}},"/api/health/latest":{"get":{"tags":["Health"],"summary":"Get latest health check result","description":"Returns the most recent cached health check result","responses":{"200":{"description":"Latest health check result","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"status":{"type":"string"},"timestamp":{"type":"string"}},"required":["success","status","timestamp"]}}}}}}},"/api/health/db-smoke":{"get":{"tags":["Health"],"summary":"Database smoke test","description":"Performs a quick database connectivity test","responses":{"200":{"description":"Database is accessible","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"database":{"type":"string"},"latency":{"type":"number"}},"required":["success","database"]}}}},"503":{"description":"Database is not accessible","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/container/status":{"get":{"tags":["Monitoring"],"summary":"Container status","description":"Returns the status of Durable Object containers","responses":{"200":{"description":"Container status","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"containers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"lastSeen":{"type":"string"}},"required":["id","status"]}}},"required":["success","containers"]}}}}}}},"/api/keys":{"post":{"tags":["API Keys"],"summary":"Create a new API key","description":"Creates a new API key for the authenticated user. Requires an interactive user session (Better Auth). The plaintext key is returned only once.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128,"description":"Human-readable name for the API key"},"scopes":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":10,"description":"Array of permission scopes"},"expiresInDays":{"type":"integer","minimum":1,"maximum":365,"description":"Optional expiration period in days"}},"required":["name","scopes"]}}}},"responses":{"201":{"description":"API key created successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"id":{"type":"string","format":"uuid"},"key":{"type":"string"},"keyPrefix":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"rateLimitPerMinute":{"type":"number"},"expiresAt":{"type":"string","nullable":true,"format":"date-time"},"createdAt":{"type":"string","format":"date-time"}},"required":["success","id","key","keyPrefix","name","scopes","rateLimitPerMinute","expiresAt","createdAt"]}}}},"400":{"description":"Validation error or key limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires interactive user session","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}},"get":{"tags":["API Keys"],"summary":"List API keys","description":"Returns all API keys for the authenticated user. Requires an interactive user session (Better Auth).","responses":{"200":{"description":"List of API keys","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"keys":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Unique identifier for the API key"},"keyPrefix":{"type":"string","description":"First few characters of the key (for identification)"},"name":{"type":"string","description":"Human-readable name"},"scopes":{"type":"array","items":{"type":"string"},"description":"Permission scopes"},"rateLimitPerMinute":{"type":"integer","minimum":0,"description":"Rate limit for this key"},"lastUsedAt":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 timestamp of last use"},"expiresAt":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 expiration timestamp"},"revokedAt":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 revocation timestamp"},"createdAt":{"type":"string","format":"date-time","description":"ISO 8601 creation timestamp"},"updatedAt":{"type":"string","format":"date-time","description":"ISO 8601 last-updated timestamp"},"isActive":{"type":"boolean","description":"Whether the key is currently active"}},"required":["id","keyPrefix","name","scopes","rateLimitPerMinute","lastUsedAt","expiresAt","revokedAt","createdAt","updatedAt","isActive"]}},"total":{"type":"integer","minimum":0}},"required":["success","keys","total"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires interactive user session","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/keys/{id}":{"delete":{"tags":["API Keys"],"summary":"Revoke an API key","description":"Soft-deletes an API key by setting its revoked_at timestamp. Requires an interactive user session (Better Auth).","parameters":[{"schema":{"type":"string","format":"uuid","description":"API key ID"},"required":true,"description":"API key ID","name":"id","in":"path"}],"responses":{"200":{"description":"API key revoked successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}},"required":["success","message"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires interactive user session","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"API key not found or already revoked","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}},"patch":{"tags":["API Keys"],"summary":"Update an API key","description":"Updates an API key's name or scopes. Requires an interactive user session (Better Auth).","parameters":[{"schema":{"type":"string","format":"uuid","description":"API key ID"},"required":true,"description":"API key ID","name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128,"description":"Updated name for the API key"},"scopes":{"type":"array","items":{"type":"string"},"minItems":1,"maxItems":10,"description":"Updated permission scopes"}}}}}},"responses":{"200":{"description":"API key updated successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"id":{"type":"string","format":"uuid"},"keyPrefix":{"type":"string"},"name":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"rateLimitPerMinute":{"type":"number"},"lastUsedAt":{"type":"string","nullable":true,"format":"date-time"},"expiresAt":{"type":"string","nullable":true,"format":"date-time"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"required":["success","id","keyPrefix","name","scopes","rateLimitPerMinute","lastUsedAt","expiresAt","createdAt","updatedAt"]}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Forbidden - requires interactive user session","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"API key not found or already revoked","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Database not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/notify":{"post":{"tags":["Webhooks"],"summary":"Send webhook notification","description":"Forwards a notification event to configured webhook targets (generic HTTP endpoint, Sentry, Datadog). Requires authentication and rate limiting.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"type":"string","minLength":1,"maxLength":128,"description":"Event identifier (e.g., \"compilation.failed\")"},"level":{"type":"string","enum":["info","warn","error"],"description":"Severity level"},"message":{"type":"string","minLength":1,"description":"Human-readable notification message"},"source":{"type":"string","description":"Source application or service name"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 event timestamp"},"metadata":{"type":"object","additionalProperties":{"nullable":true},"description":"Additional context data"}},"required":["event","message"]}}}},"responses":{"200":{"description":"Notification delivered to at least one target","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"event":{"type":"string"},"deliveries":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string","description":"Target webhook type (generic, sentry, datadog)"},"success":{"type":"boolean","description":"Whether delivery succeeded"},"statusCode":{"type":"integer","description":"HTTP status code from target"},"error":{"type":"string","description":"Error message if delivery failed"}},"required":["target","success"]}},"duration":{"type":"string","description":"Delivery duration (e.g., \"123ms\")"}},"required":["success","event","deliveries","duration"]}}}},"400":{"description":"Invalid JSON body","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"422":{"description":"Validation error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"502":{"description":"All webhook targets failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"event":{"type":"string"},"deliveries":{"type":"array","items":{"type":"object","properties":{"target":{"type":"string","description":"Target webhook type (generic, sentry, datadog)"},"success":{"type":"boolean","description":"Whether delivery succeeded"},"statusCode":{"type":"integer","description":"HTTP status code from target"},"error":{"type":"string","description":"Error message if delivery failed"}},"required":["target","success"]}},"duration":{"type":"string"}},"required":["success","event","deliveries","duration"]}}}},"503":{"description":"No webhook targets configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/stripe/webhook":{"post":{"tags":["Stripe","Webhooks"],"summary":"Stripe webhook endpoint","description":"Receives and processes Stripe subscription webhook events","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Stripe event ID"},"object":{"type":"string","enum":["event"]},"type":{"type":"string","description":"Event type (e.g., customer.subscription.created)"},"data":{"type":"object","properties":{"object":{"type":"object","additionalProperties":{"nullable":true},"description":"Event data object"}},"required":["object"]},"created":{"type":"number","description":"Unix timestamp"},"livemode":{"type":"boolean","description":"Whether event is from live or test mode"}},"required":["id","object","type","data","created","livemode"]}}}},"responses":{"200":{"description":"Webhook processed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"},"eventId":{"type":"string"}},"required":["success","message"]}}}},"400":{"description":"Invalid webhook payload or signature","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/workflow/compile":{"post":{"tags":["Workflows"],"summary":"Start a compilation workflow","description":"Triggers a long-running compilation workflow using Cloudflare Workflows. Returns immediately with a workflow ID for status polling.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"configuration":{"type":"object","additionalProperties":{"nullable":true},"description":"Compilation configuration object"},"preFetchedContent":{"type":"object","additionalProperties":{"type":"string"},"description":"Optional pre-fetched filter list content"},"benchmark":{"type":"boolean","description":"Whether to include benchmark metrics"},"priority":{"type":"string","enum":["high","normal","low"],"description":"Workflow priority"}},"required":["configuration"]}}}},"responses":{"202":{"description":"Workflow started successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string","description":"Human-readable message"},"workflowId":{"type":"string","description":"Unique workflow instance identifier"},"workflowType":{"type":"string","enum":["compilation","batch-compilation","cache-warming","health-monitoring"],"description":"Type of workflow"}},"required":["success","message","workflowId","workflowType"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Workflow bindings not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/workflow/batch":{"post":{"tags":["Workflows"],"summary":"Start a batch compilation workflow","description":"Triggers a workflow to compile multiple configurations in a single batch. Returns immediately with a workflow ID.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"requests":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Unique identifier for this batch item"},"configuration":{"type":"object","additionalProperties":{"nullable":true},"description":"Compilation configuration"},"preFetchedContent":{"type":"object","additionalProperties":{"type":"string"},"description":"Optional pre-fetched content"},"benchmark":{"type":"boolean","description":"Whether to include benchmarks"}},"required":["id","configuration"]},"minItems":1,"description":"Array of compilation requests to process in batch"},"priority":{"type":"string","enum":["high","normal","low"],"description":"Batch priority"}},"required":["requests"]}}}},"responses":{"202":{"description":"Batch workflow started successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string","description":"Human-readable message"},"workflowId":{"type":"string","description":"Unique workflow instance identifier"},"workflowType":{"type":"string","enum":["compilation","batch-compilation","cache-warming","health-monitoring"],"description":"Type of workflow"},"batchSize":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Number of items in the batch"}},"required":["success","message","workflowId","workflowType","batchSize"]}}}},"400":{"description":"Invalid batch request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Workflow bindings not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/workflow/cache-warm":{"post":{"tags":["Workflows"],"summary":"Start a cache warming workflow","description":"Triggers a workflow to pre-warm compilation caches for specified configurations. Returns immediately with a workflow ID.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"configurations":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}},"description":"Optional configurations to warm. Uses defaults if omitted."}}}}}},"responses":{"202":{"description":"Cache warming workflow started successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string","description":"Human-readable message"},"workflowId":{"type":"string","description":"Unique workflow instance identifier"},"workflowType":{"type":"string","enum":["compilation","batch-compilation","cache-warming","health-monitoring"],"description":"Type of workflow"},"configurationsCount":{"anyOf":[{"type":"integer","minimum":0},{"type":"string","enum":["default"]}],"description":"Number of configurations or \"default\""}},"required":["success","message","workflowId","workflowType","configurationsCount"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Workflow bindings not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/workflow/health-check":{"post":{"tags":["Workflows"],"summary":"Start a health monitoring workflow","description":"Triggers a workflow to check the health of filter list sources. Returns immediately with a workflow ID.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"sources":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string","description":"Human-readable source name"},"url":{"type":"string","format":"uri","description":"Source URL to check"},"expectedMinRules":{"type":"integer","minimum":0,"description":"Minimum expected rule count"}},"required":["name","url"]},"description":"Optional sources to check. Uses defaults if omitted."},"alertOnFailure":{"type":"boolean","description":"Whether to send alerts on health check failure"}}}}}},"responses":{"202":{"description":"Health monitoring workflow started successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string","description":"Human-readable message"},"workflowId":{"type":"string","description":"Unique workflow instance identifier"},"workflowType":{"type":"string","enum":["compilation","batch-compilation","cache-warming","health-monitoring"],"description":"Type of workflow"},"sourcesCount":{"anyOf":[{"type":"integer","minimum":0},{"type":"string","enum":["default"]}],"description":"Number of sources or \"default\""}},"required":["success","message","workflowId","workflowType","sourcesCount"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Workflow bindings not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/workflow/status/{type}/{id}":{"get":{"tags":["Workflows"],"summary":"Get workflow status","description":"Returns the current status of a workflow instance by type and ID","parameters":[{"schema":{"type":"string","enum":["compilation","batch-compilation","cache-warming","health-monitoring"],"description":"Workflow type"},"required":true,"description":"Workflow type","name":"type","in":"path"},{"schema":{"type":"string","description":"Workflow instance identifier"},"required":true,"description":"Workflow instance identifier","name":"id","in":"path"}],"responses":{"200":{"description":"Workflow status retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"workflowId":{"type":"string"},"workflowType":{"type":"string"},"status":{"type":"string","enum":["queued","running","paused","errored","terminated","complete","waiting","waitingForPause","unknown"],"description":"Current workflow status"},"output":{"nullable":true,"description":"Workflow output data if completed"},"error":{"nullable":true,"description":"Error information if workflow failed"}},"required":["success","workflowId","workflowType","status"]}}}},"400":{"description":"Invalid workflow type","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"404":{"description":"Workflow instance not found","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"503":{"description":"Workflow bindings not configured","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/workflow/metrics":{"get":{"tags":["Workflows"],"summary":"Get aggregated workflow metrics","description":"Returns aggregated metrics for all workflow types","responses":{"200":{"description":"Workflow metrics retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 timestamp of metrics snapshot"},"workflows":{"type":"object","properties":{"compilation":{"type":"object","properties":{"totalCompilations":{"type":"integer","minimum":0}},"required":["totalCompilations"],"additionalProperties":{"nullable":true}},"batchCompilation":{"type":"object","properties":{"totalBatches":{"type":"integer","minimum":0}},"required":["totalBatches"],"additionalProperties":{"nullable":true}},"cacheWarming":{"type":"object","properties":{"totalRuns":{"type":"integer","minimum":0}},"required":["totalRuns"],"additionalProperties":{"nullable":true}},"healthMonitoring":{"type":"object","properties":{"totalChecks":{"type":"integer","minimum":0}},"required":["totalChecks"],"additionalProperties":{"nullable":true}}},"required":["compilation","batchCompilation","cacheWarming","healthMonitoring"]}},"required":["success","timestamp","workflows"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/workflow/events/{id}":{"get":{"tags":["Workflows"],"summary":"Get workflow events","description":"Returns the event log for a specific workflow instance. Optionally filter events after a specific timestamp using the \"since\" query parameter.","parameters":[{"schema":{"type":"string","description":"Workflow instance identifier"},"required":true,"description":"Workflow instance identifier","name":"id","in":"path"},{"schema":{"type":"string","format":"date-time","description":"ISO 8601 timestamp to filter events after"},"required":false,"description":"ISO 8601 timestamp to filter events after","name":"since","in":"query"}],"responses":{"200":{"description":"Workflow events retrieved successfully","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"workflowId":{"type":"string"},"workflowType":{"type":"string"},"startedAt":{"type":"string","format":"date-time","description":"ISO 8601 workflow start time"},"completedAt":{"type":"string","format":"date-time","description":"ISO 8601 workflow completion time"},"progress":{"type":"number","minimum":0,"maximum":100,"description":"Current progress percentage"},"isComplete":{"type":"boolean","description":"Whether workflow has completed or failed"},"events":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","description":"Event type (e.g., \"workflow:started\", \"workflow:progress\", \"workflow:completed\")"},"workflowId":{"type":"string","description":"Workflow instance identifier"},"workflowType":{"type":"string","description":"Workflow type"},"timestamp":{"type":"string","format":"date-time","description":"ISO 8601 event timestamp"},"step":{"type":"string","description":"Workflow step identifier"},"progress":{"type":"number","minimum":0,"maximum":100,"description":"Progress percentage (0-100)"},"message":{"type":"string","description":"Human-readable event message"},"data":{"type":"object","additionalProperties":{"nullable":true},"description":"Additional event data"}},"required":["type","workflowId","workflowType","timestamp"]},"description":"Array of workflow events"},"message":{"type":"string","description":"Message when no events found"}},"required":["success","workflowId","events"]}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/proxy/fetch":{"get":{"tags":["Proxy"],"summary":"Proxy fetch a single URL","description":"Fetches the content of a remote HTTPS URL on behalf of the client.\n\nThis endpoint exists to allow browser-based (local mode) and hybrid mode\ncompilation to download source filter lists that would otherwise be blocked\nby browser CORS policies.\n\n**SSRF protection** — private/loopback/link-local IP ranges and cloud metadata\nendpoints (`169.254.169.254`, `metadata.google.internal`) are blocked.\n\n**Caching** — responses are cached in KV for 5 minutes to reduce upstream load.\n\n**Auth** — anonymous callers must pass a valid Cloudflare Turnstile token via the\n`X-Turnstile-Token` request header. Authenticated (Free+) callers are exempt.","parameters":[{"schema":{"type":"string","format":"uri","description":"Fully-qualified HTTPS URL to fetch (URL-encoded)"},"required":true,"description":"Fully-qualified HTTPS URL to fetch (URL-encoded)","name":"url","in":"query"},{"schema":{"type":"string","description":"Turnstile token for anonymous callers"},"required":false,"description":"Turnstile token for anonymous callers","name":"turnstileToken","in":"query"}],"responses":{"200":{"description":"Raw text content of the proxied URL","content":{"text/plain":{"schema":{"type":"string"}}}},"400":{"description":"Invalid or unsafe URL","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"403":{"description":"Turnstile verification failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}},"502":{"description":"Upstream fetch failed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}},"/api/proxy/fetch/batch":{"post":{"tags":["Proxy"],"summary":"Batch proxy fetch multiple URLs","description":"Fetches the content of multiple remote HTTPS URLs in parallel.\n\nUsed by **hybrid mode**: the Worker fetches source filter lists and returns\nthe raw content to the browser, which then runs the transformation pipeline\nlocally via `WorkerCompiler`.\n\nRequires **Pro tier** — enforced by the route permission registry.\n\nMaximum **20 URLs** per request.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"urls":{"type":"array","items":{"type":"string","format":"uri"},"minItems":1,"maxItems":20,"description":"HTTPS URLs to fetch"}},"required":["urls"]}}}},"responses":{"200":{"description":"Map of URL → fetched content (or error message)","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"results":{"type":"object","additionalProperties":{"type":"object","properties":{"content":{"type":"string"},"error":{"type":"string"}}}}},"required":["success","results"]}}}},"400":{"description":"Invalid request body","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"string"}},"required":["success","error"]}}}}}}}}}