{"openapi":"3.1.0","info":{"title":"Annotate API","version":"1.0.0","description":"Public API for Annotate report ingestion, dashboard workflows, team management, and integrations."},"servers":[{"url":"https://annotate-api-production.up.railway.app"}],"tags":[{"name":"Auth"},{"name":"Reports"},{"name":"Projects"},{"name":"Teams"},{"name":"Integrations"},{"name":"Audit"},{"name":"Compliance"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}},"schemas":{"Environment":{"type":"object","required":["browser","browser_version","os","os_version","viewport_width","viewport_height"],"properties":{"browser":{"type":"string"},"browser_version":{"type":"string"},"os":{"type":"string"},"os_version":{"type":"string"},"viewport_width":{"type":"integer"},"viewport_height":{"type":"integer"},"device_type":{"type":"string","enum":["mobile","tablet","desktop"]},"language":{"type":"string"},"connection_type":{"type":"string"}}},"Report":{"type":"object","properties":{"id":{"type":"string"},"project_id":{"type":"string"},"type":{"type":"string","enum":["bug","feedback","question","praise"]},"priority":{"type":"string","enum":["critical","high","medium","low"]},"status":{"type":"string","enum":["open","triaged","in_progress","resolved","duplicate"]},"comment":{"type":"string"},"page_url":{"type":"string"},"element_path":{"type":"string"},"screenshot_url":{"type":["string","null"]},"github_issue_url":{"type":["string","null"]},"reporter_email":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"}}},"Project":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"api_key":{"type":["string","null"]},"owner_id":{"type":"string"},"repo_url":{"type":["string","null"]},"slack_webhook_url":{"type":["string","null"]},"slack_rotation_required":{"type":"boolean"},"github_rotation_required":{"type":"boolean"},"retention_days":{"type":["integer","null"]},"github_set":{"type":"boolean"},"access_role":{"type":"string","enum":["owner","admin","member"]},"created_at":{"type":"string"}}}}},"paths":{"/health":{"get":{"summary":"Health check","responses":{"200":{"description":"API and database are healthy"}}}},"/auth/register":{"post":{"tags":["Auth"],"summary":"Create an account","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password","name"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8},"name":{"type":"string"},"invite_token":{"type":"string"}}}}}},"responses":{"201":{"description":"JWT and user object"},"409":{"description":"Email already registered"}}}},"/auth/login":{"post":{"tags":["Auth"],"summary":"Sign in","responses":{"200":{"description":"JWT and user object"},"401":{"description":"Invalid credentials"},"429":{"description":"Too many failed attempts"}}}},"/auth/forgot-password":{"post":{"tags":["Auth"],"summary":"Request a password reset email","responses":{"200":{"description":"Generic reset response"}}}},"/auth/reset-password":{"post":{"tags":["Auth"],"summary":"Reset password and revoke previous sessions","responses":{"200":{"description":"Password reset complete"},"400":{"description":"Invalid or expired token"}}}},"/projects":{"get":{"tags":["Projects"],"security":[{"bearerAuth":[]}],"summary":"List owned and shared projects","responses":{"200":{"description":"Project list"}}},"post":{"tags":["Projects"],"security":[{"bearerAuth":[]}],"summary":"Create a project","responses":{"201":{"description":"Project with API key"},"409":{"description":"Duplicate project name"}}}},"/projects/{id}/retention":{"put":{"tags":["Projects"],"security":[{"bearerAuth":[]}],"summary":"Set or clear owner-managed report retention days","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Retention policy updated"},"404":{"description":"Project not found"}}}},"/projects/{id}/retention/purge":{"post":{"tags":["Projects"],"security":[{"bearerAuth":[]}],"summary":"Delete reports older than the configured retention period","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Expired report deletion count"},"400":{"description":"Retention policy not configured"}}}},"/audit-logs":{"get":{"tags":["Audit"],"security":[{"bearerAuth":[]}],"summary":"List admin-visible audit events","parameters":[{"name":"project_id","in":"query","schema":{"type":"string"}},{"name":"action","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200}}],"responses":{"200":{"description":"Audit event list"}}}},"/legal":{"get":{"tags":["Compliance"],"summary":"Buyer legal and compliance packet index","responses":{"200":{"description":"HTML index of available compliance artifacts"}}}},"/legal/{slug}":{"get":{"tags":["Compliance"],"summary":"Fetch a buyer legal or compliance artifact as Markdown","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Markdown compliance document"},"404":{"description":"Unknown document"}}}},"/reports":{"get":{"tags":["Reports"],"security":[{"bearerAuth":[]}],"summary":"List reports with filters and cursor pagination","parameters":[{"name":"project_id","in":"query","schema":{"type":"string"}},{"name":"type","in":"query","schema":{"type":"string"}},{"name":"priority","in":"query","schema":{"type":"string"}},{"name":"status","in":"query","schema":{"type":"string"}},{"name":"q","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated reports"}}},"post":{"tags":["Reports"],"summary":"Ingest a widget report with project API key","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["api_key","type","priority","comment","page_url","environment"],"properties":{"api_key":{"type":"string"},"type":{"type":"string","enum":["bug","feedback","question","praise"]},"priority":{"type":"string","enum":["critical","high","medium","low"]},"comment":{"type":"string"},"page_url":{"type":"string"},"element_path":{"type":"string"},"screenshot_data":{"type":"string"},"environment":{"$ref":"#/components/schemas/Environment"},"console_entries":{"type":"array"},"network_entries":{"type":"array"},"session_events":{"type":"array"},"user_context":{"type":"object"}}}}}},"responses":{"201":{"description":"Report accepted"},"401":{"description":"Invalid API key"}}}},"/reports/export.csv":{"get":{"tags":["Reports"],"security":[{"bearerAuth":[]}],"summary":"Export filtered reports as formula-safe CSV","responses":{"200":{"description":"CSV file"}}}},"/reports/{id}/screenshot":{"get":{"tags":["Reports"],"security":[{"bearerAuth":[]}],"summary":"Fetch a private report screenshot","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"PNG screenshot"},"404":{"description":"Screenshot not found"}}}},"/reports/{id}/triage":{"post":{"tags":["Reports"],"security":[{"bearerAuth":[]}],"summary":"Run AI triage. Pro plan required.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Server-sent events with triage output"},"402":{"description":"Pro plan required"}}}},"/reports/{id}/create-issue":{"post":{"tags":["Integrations"],"security":[{"bearerAuth":[]}],"summary":"Create a GitHub issue from a report. Requires project repo URL and GitHub token.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"GitHub issue URL"},"400":{"description":"Missing repo URL or token"}}}},"/reports/{id}/create-pr":{"post":{"tags":["Integrations"],"security":[{"bearerAuth":[]}],"summary":"Create an AI-generated GitHub PR. Pro plan required.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"GitHub PR URL"},"402":{"description":"Pro plan required"}}}}}}