{"openapi":"3.0.3","info":{"title":"GoOmni AI","description":"AI-powered project management, quality assurance, and knowledge platform.\n\n**Base URL:** `https://agent.goomni.ai` &nbsp;|&nbsp; **Auth:** `Authorization: Bearer <jwt>`\n","version":"1.0.0","contact":{"name":"GoOmni API Support","url":"https://goomni.ai"},"license":{"name":"Proprietary","url":"https://goomni.ai/terms"}},"servers":[{"url":"https://agent.goomni.ai","description":"Production"},{"url":"http://localhost:3000","description":"Local Development"}],"tags":[{"name":"Organizations","description":"**Top-level tenant.** Every resource belongs to an organization.\nCreate an org first, then create projects and knowledge bases under it.\n"},{"name":"Organization Team","description":"Invite members, assign roles, manage team within an organization"},{"name":"Organization Preferences","description":"Custom prompts, model preferences, and org-level settings"},{"name":"Projects","description":"**Scoped workspaces** under an organization. A project groups related work:\nRFP responses, QA test suites, site migrations, etc. Link knowledge bases\nto projects to give them context.\n"},{"name":"Project Files","description":"Upload, list, preview, reindex, and manage files within a project"},{"name":"Knowledge Bases","description":"**AI-powered document stores** under an organization. Upload files, crawl websites,\nor connect Google Drive. Content is chunked, embedded, and indexed for semantic search.\n"},{"name":"Knowledge Base Files","description":"Upload, list, preview, delete, and retry files within a knowledge base"},{"name":"Knowledge Base Search","description":"Semantic search (RAG) across knowledge base content"},{"name":"PM Stories","description":"User stories following INVEST criteria. Each story is a test basis per ISTQB.\nCreate, estimate, and auto-generate test cases from stories.\n"},{"name":"PM Estimation","description":"AI-powered story pointing using modified Fibonacci scale with risk-based adjustment"},{"name":"PM Sprints","description":"Sprint management with AI-powered planning, velocity tracking, and story assignment"},{"name":"PM Documentation","description":"Auto-generate user manuals and release notes from stories and test results"},{"name":"PM Risks","description":"AI risk analysis using Rex Black's risk-based testing methodology.\nLikelihood x Impact scoring, compliance gap analysis, and test priority recommendations.\n"},{"name":"PM Integrations","description":"Push stories, test cases, and defects directly to Jira, Asana, Linear, and Azure DevOps.\nUses official SDKs (jira.js, asana, @linear/sdk, azure-devops-node-api) for real integrations.\nTest connection, push items, and auto-sync from the GoOmni QA/PM lifecycle.\n"},{"name":"Public Test Case Generator","description":"**No authentication.** Powers the public-facing Test Case Generator at\n`/public/test-case-generator`. Agentic, multi-turn generation backed by a\nClaude tool-use loop with KB grounding (Rex Black, ISTQB) and file-to-\nrequirements extraction. Rate-limited per email.\n\nStreams real-time progress via WebSocket, POST returns an `executionId`,\nthen `wss://<api>/ws` with `{action: \"subscribe\", executionId}` delivers\n`status` / `result` / `execution_complete` events.\n"},{"name":"Public Test Sessions","description":"Persistent generation sessions. Tracks the requirements input, conversation\nturns, generated test cases, and lets the UI autosave inline edits via PATCH.\n"},{"name":"Public Hosted Execution","description":"Dispatches a hosted browser run for a subset of test cases against a\ntarget URL. Each prose test step is interpreted by Claude into typed\nbrowser actions (puppeteer-core + @sparticuz/chromium on AWS Lambda),\nverified, and captured as PNG evidence in S3. Returns `executionId`\nimmediately, the frontend subscribes via WebSocket for step-level\nprogress and pulls signed-URL evidence when the run completes.\n\n**Free-tier limit:** 5 executions per hour per email.\n"},{"name":"Public Test Case Export","description":"Render generated test cases into 6 deliverable formats:\nJira Xray CSV, TestRail CSV, Azure DevOps CSV, generic CSV,\nGherkin .feature, and structured JSON.\n"},{"name":"QA Setup","description":"QA onboarding wizard - readiness checks and setup status"},{"name":"QA Test Cases","description":"Generate and export test cases from project requirements"},{"name":"QA Requirements","description":"Extract testable requirements from uploaded documents"},{"name":"QA Knowledge","description":"Query QA training materials for definitions and best practices"},{"name":"QA Traceability","description":"Full requirements traceability matrix (Story -> Test Cases -> Executions -> Defects).\nLive data from your project. Essential for compliance audits and ISTQB process improvement.\n"},{"name":"QA Test Scripts","description":"Export test cases as runnable Playwright, Cypress, Selenium, or Puppeteer scripts.\nComplete files with page objects, helpers, config, and package.json, ready to commit to your repo.\n"},{"name":"QA Test Execution","description":"Real browser test execution using Puppeteer/Chromium against your live URL.\nParallel execution (up to 10 browsers), self-healing selectors, screenshots at each step.\n"},{"name":"QA Defects","description":"Bug/defect tracking linked to stories, test cases, and executions.\nAuto-created when browser tests fail. Full lifecycle: open -> in_progress -> fixed -> verified -> closed.\n"},{"name":"QA BDD","description":"First-class BDD/Gherkin generation. Produces complete .feature files with step definitions.\nSupports Cucumber, Behave, SpecFlow, Cypress-Cucumber, Playwright-BDD.\n"},{"name":"QA CI/CD","description":"CI/CD webhook triggers for automated test execution from GitHub Actions, Jenkins,\nGitLab CI, Azure DevOps. Includes callback URL for status reporting.\n"},{"name":"Voice","description":"AI voice agent phone system - manage calls and phone numbers"},{"name":"Voice Tools","description":"Tools that voice agents can invoke during calls"},{"name":"Voice Outbound","description":"Initiate outbound calls and manage call campaigns"},{"name":"Campaigns","description":"Outbound call campaigns with contact lists"},{"name":"SMS","description":"SMS messaging"},{"name":"RFP","description":"RFP analysis and proposal generation (project-scoped)"},{"name":"RFP Agents","description":"AI agent chain for RFP workflows"},{"name":"Opportunities","description":"Government/enterprise procurement opportunity scanning"},{"name":"Document Accessibility","description":"WCAG 2.1 / Section 508 / ADA compliance auditing for PDFs and documents.\nChecks tagged structure, reading order, alt text, headings, bookmarks, form labels,\ncolor contrast, and more. Returns compliance score and prioritized remediation plan.\n"},{"name":"Document Analytics","description":"Multi-analysis engine: Flesch reading ease, grade-level scoring, structure breakdown,\nmetadata extraction, language detection, quality scoring, and AI-powered summaries.\n"},{"name":"Document PII","description":"Scan documents for personally identifiable information: SSNs, credit cards, emails,\nphone numbers, addresses, dates of birth, driver's licenses, passport numbers, bank accounts,\nand medical records. Optional redaction with configurable category filtering.\n"},{"name":"Files","description":"File upload, download, and processing"},{"name":"Search","description":"Unified search across projects and knowledge bases"},{"name":"Website Crawling","description":"Full website crawling, indexing, and pipeline management"},{"name":"Site Analysis","description":"Lighthouse SEO/performance/accessibility analysis"},{"name":"Content Type Analysis","description":"CMS content type detection and migration planning"},{"name":"Page Transformation","description":"Page migration preview, navigation strategy"},{"name":"Master Context","description":"AI-generated master context from KB or project content"},{"name":"Voice Context","description":"Voice agent context and FAQ generation"},{"name":"Ontology","description":"Entity and relationship extraction (knowledge graph)"},{"name":"Validation","description":"PII detection, compliance, quality, citation validation"},{"name":"Analytics Ingestion","description":"**Public, no auth.** Tracker endpoints that accept pageviews, custom events,\nidentify payloads, and session replay chunks. Events queue through SQS into\nClickHouse. Use `/api/collect` for new integrations; `/api/analytics/send`\nis a legacy alias.\n"},{"name":"Analytics Privacy","description":"Per-website masking, DNT, geo-only, and performance-gate policy. GET is\npublic (tracker init); PATCH requires org admin.\n"},{"name":"PostHog Proxy","description":"Self-hosted `posthog-js` compatibility layer. Implements `decide` for survey\nmatching and proxies capture calls (survey events only). Customer data never\nleaves GoOmni infrastructure.\n"},{"name":"Heatmaps","description":"Click, mouse-move, and scroll-depth heatmaps aggregated from tracker events.\nBuilder and screenshot workers materialize grids in S3.\n"},{"name":"Session Replay","description":"rrweb-based session recordings. Ingest via `/api/record`; playback via\nauthenticated manifest + ClickHouse chunk fetch.\n"},{"name":"Experiments","description":"GrowthBook-powered A/B tests with DOM mutation variants, goals, and exposure\ntracking. Runtime config is served to the tracker; stats live in ClickHouse.\n"},{"name":"Surveys","description":"In-product surveys with PostHog-compatible JSON shape. Matched via\n`/api/posthog/decide` and rendered by `posthog-js` against your host.\n"},{"name":"Guided Flows","description":"Product tours and onboarding checklists served to the tracker."},{"name":"Forms Analytics","description":"Field-level form metrics aggregated from custom events on `/api/collect`."},{"name":"Analytics Websites","description":"Website CRUD, share links, and console configuration. Each website UUID is\nthe tracker `siteKey`.\n"},{"name":"Analytics Metrics","description":"Stats, time-series, pageviews, custom events, and event-data fields."},{"name":"Analytics Reports","description":"Funnel, retention, goals, journey, and saved reports."},{"name":"Analytics Realtime","description":"Active visitors and live pageview feed (30-minute window)."},{"name":"Analytics Teams","description":"Team membership and shared website access for the analytics console."},{"name":"Ticket Sync","description":"Pull and normalize tickets from Jira, Asana, Linear, Azure DevOps"},{"name":"Ticket Analysis","description":"AI-powered ticket quality scoring with improvement suggestions"},{"name":"Ticket Generation","description":"Create structured agile tickets from raw input (email, support, webhook, Slack)"},{"name":"Ticket Enhancement","description":"Apply Scrum/Kanban/hybrid best practices to existing tickets"},{"name":"Ticket Deduplication","description":"Semantic duplicate detection across the full ticket landscape"},{"name":"Ticket Status","description":"Intelligent status lookup: \"Has this bug been fixed?\" Returns matching tickets,\ncurrent status, and recommendation (create_new, in_progress, already_resolved, consolidate).\n"},{"name":"Ticket Consolidation","description":"Merge cross-channel duplicate tickets into canonical entries"},{"name":"Ticket Inbound","description":"Multi-channel ticket intake from email, support forms, Slack, webhooks.\nIncludes a public webhook endpoint for machine-to-machine integrations\n(SendGrid, Mailgun, Intercom, Zendesk).\n"},{"name":"Dev Workflow","description":"Developer-facing endpoints for Cursor/CoPilot integration.\nBrowse tickets, claim with AI execution plan, mark complete and update PM tool.\n"},{"name":"Integrations","description":"External service connections (Twilio, HubSpot)"},{"name":"Google Drive","description":"Google Drive file import, indexing, and folder management"},{"name":"Agent Runs","description":"Agent execution history and logs (project-scoped)"}],"security":[{"bearerAuth":[]}],"components":{"parameters":{"organizationId":{"name":"organizationId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Organization ID (top-level tenant identifier)"},"projectId":{"name":"projectId","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Project ID (scoped workspace within an organization)"},"kbId":{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"},"description":"Knowledge Base ID"}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT token from NextAuth/Cognito authentication"}},"schemas":{"AnalyticsWebsite":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"domain":{"type":"string","nullable":true},"organizationId":{"type":"string","format":"uuid"},"teamId":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"CollectRequest":{"type":"object","required":["type","payload"],"properties":{"type":{"type":"string","enum":["event","identify"],"description":"`event` records a pageview or custom event. `identify` attaches\nsession properties via the session_data pipeline.\n"},"payload":{"type":"object","required":["website"],"properties":{"website":{"type":"string","format":"uuid","description":"Website ID from the analytics console (tracker site key)."},"url":{"type":"string"},"title":{"type":"string"},"referrer":{"type":"string"},"hostname":{"type":"string"},"language":{"type":"string"},"screen":{"type":"string"},"name":{"type":"string","description":"Custom event name (omit for pageviews)."},"specialEventName":{"type":"string"},"tag":{"type":"string","nullable":true},"data":{"type":"object","additionalProperties":true,"description":"Custom event properties."},"session":{"type":"object","additionalProperties":true}}}}},"RecordRequest":{"type":"object","required":["type","payload"],"properties":{"type":{"type":"string","enum":["record"]},"payload":{"type":"object","required":["website","events"],"properties":{"website":{"type":"string","format":"uuid"},"events":{"type":"array","minItems":1,"maxItems":200,"items":{"type":"object","description":"rrweb recording chunk events."}},"timestamp":{"type":"integer","format":"int64"}}}}},"Heatmap":{"type":"object","properties":{"heatmapId":{"type":"string","format":"uuid"},"websiteId":{"type":"string","format":"uuid"},"urlPath":{"type":"string"},"device":{"type":"string","enum":["desktop","mobile","tablet"]},"status":{"type":"string","enum":["pending","building","ready","failed"]},"windowStart":{"type":"string","format":"date-time"},"windowEnd":{"type":"string","format":"date-time"}}},"ReplaySessionSummary":{"type":"object","properties":{"replaySessionId":{"type":"string"},"websiteId":{"type":"string","format":"uuid"},"sessionId":{"type":"string"},"startedAt":{"type":"string","format":"date-time"},"endedAt":{"type":"string","format":"date-time"},"durationMs":{"type":"integer"},"eventCount":{"type":"integer"},"errorCount":{"type":"integer"},"rageClickCount":{"type":"integer"},"deadClickCount":{"type":"integer"},"device":{"type":"string"},"browser":{"type":"string"},"country":{"type":"string"},"landingUrl":{"type":"string"},"exitUrl":{"type":"string"},"status":{"type":"string","enum":["recording","finalized","failed",""]},"qualityScore":{"type":"number"},"chunkCount":{"type":"integer"},"playable":{"type":"boolean"}}},"Experiment":{"type":"object","properties":{"experimentId":{"type":"string","format":"uuid"},"websiteId":{"type":"string","format":"uuid"},"name":{"type":"string"},"status":{"type":"string","enum":["draft","running","paused","completed","archived"]},"hypothesis":{"type":"string"},"variants":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"weight":{"type":"number"},"isControl":{"type":"boolean"}}}}}},"Error":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}}},"Organization":{"type":"object","properties":{"organizationId":{"type":"string","format":"uuid","description":"Unique organization identifier"},"name":{"type":"string","example":"Acme Corp"},"slug":{"type":"string","example":"acme-corp","description":"URL-friendly identifier"},"tier":{"type":"string","enum":["startup","growth","enterprise"]},"billingEmail":{"type":"string","format":"email"},"settings":{"type":"object","properties":{"chatModel":{"type":"string"},"chatTemperature":{"type":"number"},"maxMembers":{"type":"integer"},"maxProjects":{"type":"integer"},"maxStorage":{"type":"integer"},"allowPublicKBs":{"type":"boolean"},"customBranding":{"type":"boolean"}}},"googleDriveLinked":{"type":"boolean"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"Project":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid","description":"Unique project identifier"},"organizationId":{"type":"string","format":"uuid","description":"Parent organization"},"name":{"type":"string","example":"Q1 2026 Government RFP"},"description":{"type":"string"},"templateId":{"type":"string"},"templateType":{"type":"string","enum":["rfp","migration","qa","blank"]},"knowledgeBaseIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Linked knowledge bases providing context for this project"},"agentConfigs":{"type":"array","items":{"type":"object","properties":{"agentId":{"type":"string"},"agentType":{"type":"string"},"enabled":{"type":"boolean"},"order":{"type":"integer"},"config":{"type":"object"}}}},"status":{"type":"string","enum":["active","archived","deleted"]},"stats":{"type":"object","properties":{"fileCount":{"type":"integer"},"agentRunCount":{"type":"integer"},"lastActivityAt":{"type":"string","format":"date-time"}}},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"KnowledgeBase":{"type":"object","properties":{"kbId":{"type":"string","format":"uuid","description":"Unique knowledge base identifier"},"organizationId":{"type":"string","format":"uuid","description":"Parent organization"},"name":{"type":"string","example":"Company Training Materials"},"description":{"type":"string"},"type":{"type":"string","enum":["drive_folders","manual_files","integration","website"],"description":"How content is ingested"},"isPublic":{"type":"boolean","description":"Whether KB is publicly searchable"},"publicSlug":{"type":"string"},"fileCount":{"type":"integer"},"totalSizeBytes":{"type":"integer"},"embeddingModel":{"type":"string"},"status":{"type":"string","enum":["active","indexing","error","archived"]},"masterContext":{"type":"string","description":"AI-generated summary of all KB content"},"createdBy":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"KnowledgeBaseCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string","example":"Company Policies"},"description":{"type":"string","example":"Internal company policies and procedures"},"isPublic":{"type":"boolean","default":false}}},"FileUpload":{"type":"object","properties":{"fileId":{"type":"string","format":"uuid"},"fileName":{"type":"string"},"fileType":{"type":"string"},"fileSize":{"type":"integer"},"status":{"type":"string","enum":["uploaded","processing","indexed","error"]},"createdAt":{"type":"string","format":"date-time"}}},"SearchRequest":{"type":"object","required":["question"],"properties":{"question":{"type":"string","description":"The search question to ask the knowledge base","example":"What is our refund policy?"},"conversationHistory":{"type":"array","items":{"type":"object"},"description":"Previous conversation messages for context"},"enableWebSearch":{"type":"boolean","default":false},"stream":{"type":"boolean","default":false},"limit":{"type":"integer","minimum":1,"maximum":200,"default":10,"description":"Maximum number of source chunks to return. In non-streaming mode this\nis also the page size unless `perPage` is provided. Capped at 200 per\nrequest; use `page` to retrieve additional results.\n"},"page":{"type":"integer","minimum":1,"default":1,"description":"1-indexed page number for paginating through source results.\nNon-streaming mode only. The total crawl depth (page × perPage) is\ncapped at 1000 sources per query.\n"},"perPage":{"type":"integer","minimum":1,"maximum":200,"description":"Page size for pagination. Defaults to `limit` if not provided.\nNon-streaming mode only.\n"}}},"SearchPagination":{"type":"object","properties":{"page":{"type":"integer","description":"Current 1-indexed page"},"perPage":{"type":"integer","description":"Page size used for this response"},"total":{"type":"integer","description":"Total source chunks retrieved across all pages for this query\n(bounded by the 1000-source crawl cap).\n"},"hasMore":{"type":"boolean","description":"True if additional pages may exist"}}},"SearchResponse":{"type":"object","properties":{"answer":{"type":"string","description":"LLM-generated answer (always reflects the top source set, even when you page through results)"},"sources":{"type":"array","items":{"type":"object"}},"entities":{"type":"array","items":{"type":"object"}},"relationships":{"type":"array","items":{"type":"object"}},"question":{"type":"string"},"kbName":{"type":"string"},"pagination":{"$ref":"#/components/schemas/SearchPagination"}}},"SearchResult":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"chunkId":{"type":"string"},"content":{"type":"string"},"score":{"type":"number","format":"float"},"metadata":{"type":"object","properties":{"fileName":{"type":"string"},"fileId":{"type":"string"},"pageNumber":{"type":"integer"}}}}}},"totalResults":{"type":"integer"}}},"Integration":{"type":"object","properties":{"integrationId":{"type":"string"},"type":{"type":"string","enum":["twilio","hubspot","google-drive"]},"status":{"type":"string","enum":["active","inactive","error"]},"config":{"type":"object"}}},"PublicTestStep":{"type":"object","required":["stepNumber","action","expectedResult"],"properties":{"stepNumber":{"type":"integer"},"action":{"type":"string","description":"Prose instruction (e.g. \"Click the Sign Up button\")"},"expectedResult":{"type":"string","description":"Verification target (e.g. \"User is redirected to /verify-email\")"},"testData":{"type":"string"}}},"PublicTestCase":{"type":"object","required":["id","title"],"properties":{"id":{"type":"string","example":"TC-001"},"title":{"type":"string"},"description":{"type":"string"},"objective":{"type":"string"},"testBasis":{"type":"string","description":"Source requirement (e.g. user story ID)"},"testCondition":{"type":"string"},"designTechnique":{"type":"string","example":"equivalence-partitioning"},"testLevel":{"type":"string","enum":["unit","integration","system","acceptance"],"default":"system"},"testType":{"type":"string","enum":["functional","regression","integration","e2e","accessibility","security","performance","boundary","negative","smoke"],"default":"functional"},"preconditions":{"type":"array","items":{"type":"string"}},"steps":{"type":"array","items":{"$ref":"#/components/schemas/PublicTestStep"}},"expectedResult":{"type":"string"},"postconditions":{"type":"array","items":{"type":"string"}},"priority":{"type":"string","enum":["critical","high","medium","low"],"default":"medium"},"riskLevel":{"type":"string"},"category":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"requirementRef":{"type":"string"},"gherkin":{"type":"string"},"estimatedDuration":{"type":"string"}}},"PublicConversationTurn":{"type":"object","properties":{"role":{"type":"string","enum":["user","assistant"]},"content":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"testCaseCount":{"type":"integer"}}},"PublicSessionDetail":{"type":"object","properties":{"sessionId":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"requirements":{"type":"string"},"scope":{"type":"string"},"format":{"type":"string"},"maxTestCases":{"type":"integer"},"uploadedFileName":{"type":"string"},"conversation":{"type":"array","items":{"$ref":"#/components/schemas/PublicConversationTurn"}},"testCases":{"type":"array","items":{"$ref":"#/components/schemas/PublicTestCase"}},"summary":{"type":"object"},"events":{"type":"array","items":{"type":"object"}},"totalTestCases":{"type":"integer"},"totalIterations":{"type":"integer"},"totalToolCalls":{"type":"integer"},"turnCount":{"type":"integer"},"latestExecutionId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"PublicStepResult":{"type":"object","properties":{"stepNumber":{"type":"integer"},"action":{"type":"string"},"status":{"type":"string","enum":["passed","failed","error","skipped"]},"durationMs":{"type":"integer"},"screenshotKey":{"type":"string","description":"S3 key of the post-step screenshot (use the parent case's screenshotUrls for signed URL)"},"error":{"type":"string"},"interpretedAction":{"type":"object","description":"The typed browser action Claude derived from the prose step.\nShape varies by action, examples below:\n","example":{"type":"click","selector":"button:has-text('Sign Up')"}}}},"TestCase":{"type":"object","properties":{"id":{"type":"string","example":"TC-001"},"title":{"type":"string","example":"Verify login with valid credentials"},"description":{"type":"string"},"preconditions":{"type":"array","items":{"type":"string"}},"steps":{"type":"array","items":{"type":"object","properties":{"stepNumber":{"type":"integer"},"action":{"type":"string"},"expectedResult":{"type":"string"},"testData":{"type":"string"}}}},"expectedResult":{"type":"string"},"priority":{"type":"string","enum":["critical","high","medium","low"]},"type":{"type":"string","enum":["functional","regression","integration","e2e","accessibility","security","performance","boundary","negative","smoke"]},"category":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"requirementRef":{"type":"string","description":"Source requirement ID for traceability"},"gherkin":{"type":"string","description":"Given/When/Then syntax (when format is gherkin)"},"estimatedDuration":{"type":"string","example":"5min"}}},"Requirement":{"type":"object","properties":{"id":{"type":"string","example":"REQ-001"},"statement":{"type":"string","example":"The system shall authenticate users via username and password"},"category":{"type":"string","enum":["functional","security","performance","accessibility","usability","reliability"]},"subcategory":{"type":"string"},"priority":{"type":"string","enum":["critical","high","medium","low"]},"testability":{"type":"string","enum":["high","medium","low"]},"testabilityNotes":{"type":"string"},"suggestedTestType":{"type":"string"},"acceptanceCriteria":{"type":"array","items":{"type":"string"}},"ambiguities":{"type":"array","items":{"type":"string"}},"dependencies":{"type":"array","items":{"type":"string"}},"source":{"type":"string"}}},"RfpAnalysisRequest":{"type":"object","required":["projectId"],"properties":{"projectId":{"type":"string","description":"Project containing RFP files"},"kbIds":{"type":"array","items":{"type":"string"},"description":"Knowledge base IDs for company context"}}},"RfpSection":{"type":"object","properties":{"sectionId":{"type":"string"},"title":{"type":"string"},"content":{"type":"string"},"order":{"type":"integer"},"status":{"type":"string","enum":["draft","generated","reviewed","final"]}}},"AgentChainRequest":{"type":"object","required":["projectId","organizationId"],"properties":{"projectId":{"type":"string"},"organizationId":{"type":"string"},"agents":{"type":"array","items":{"type":"string","enum":["analysis","assessment","research","win-themes","writer","qa"]},"description":"Agents to run (defaults to full chain)"},"companyKbIds":{"type":"array","items":{"type":"string"},"description":"Company knowledge base IDs for context"}}},"OpportunityScanRequest":{"type":"object","required":["filterId"],"properties":{"filterId":{"type":"string","description":"Search filter ID defining scan criteria"},"organizationId":{"type":"string"},"projectId":{"type":"string"}}},"Opportunity":{"type":"object","properties":{"opportunityId":{"type":"string"},"title":{"type":"string"},"agency":{"type":"string"},"postedDate":{"type":"string","format":"date"},"dueDate":{"type":"string","format":"date"},"estimatedValue":{"type":"number"},"naicsCode":{"type":"string"},"setAside":{"type":"string"},"sourceUrl":{"type":"string"},"qualificationScore":{"type":"number","format":"float"},"status":{"type":"string","enum":["new","qualified","reviewed","applied","won","lost"]}}},"NormalizedTicket":{"type":"object","properties":{"externalId":{"type":"string","description":"Platform-specific ID (e.g. PROJ-42 for Jira, gid for Asana)"},"platform":{"type":"string","enum":["asana","jira","linear","azure_devops"]},"url":{"type":"string","format":"uri"},"title":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"},"priority":{"type":"string","enum":["critical","high","medium","low"]},"type":{"type":"string"},"assignee":{"type":"string"},"labels":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"parentId":{"type":"string"},"subtaskIds":{"type":"array","items":{"type":"string"}},"storyPoints":{"type":"integer"},"customFields":{"type":"object"}}},"GeneratedTicket":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"type":{"type":"string","enum":["feature","bug","task","spike"]},"priority":{"type":"string","enum":["critical","high","medium","low"]},"acceptanceCriteria":{"type":"array","items":{"type":"string"}},"storyPoints":{"type":"integer"},"labels":{"type":"array","items":{"type":"string"}},"relatedTicketIds":{"type":"array","items":{"type":"string"}}}},"TicketSyncResult":{"type":"object","properties":{"integrationId":{"type":"string"},"platform":{"type":"string"},"totalFetched":{"type":"integer"},"newTickets":{"type":"integer"},"updatedTickets":{"type":"integer"},"errors":{"type":"array","items":{"type":"string"}},"syncedAt":{"type":"string","format":"date-time"}}},"VoiceCall":{"type":"object","properties":{"callId":{"type":"string"},"kbId":{"type":"string"},"direction":{"type":"string","enum":["inbound","outbound"]},"fromNumber":{"type":"string"},"toNumber":{"type":"string"},"status":{"type":"string","enum":["initiated","ringing","in-progress","completed","failed"]},"duration":{"type":"integer","description":"Call duration in seconds"},"transcript":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"OutboundCallRequest":{"type":"object","required":["kbId","phoneNumber"],"properties":{"kbId":{"type":"string","format":"uuid","description":"Knowledge base ID (determines which voice agent handles the call)"},"phoneNumber":{"type":"string","description":"Phone number to call (E.164 format)","example":"+12125551234"},"metadata":{"type":"object","properties":{"contactName":{"type":"string"},"campaignId":{"type":"string"}}}}},"VoiceTool":{"type":"object","properties":{"toolId":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["lead-collection","search-faq","hubspot-meeting-booking","hubspot-meeting-availability","retrieve-kb-info","custom"]},"description":{"type":"string"},"config":{"type":"object"},"kbIds":{"type":"array","items":{"type":"string"}}}},"Campaign":{"type":"object","properties":{"campaignId":{"type":"string"},"name":{"type":"string"},"kbId":{"type":"string"},"status":{"type":"string","enum":["draft","active","paused","completed"]},"totalContacts":{"type":"integer"},"contactsCalled":{"type":"integer"},"createdAt":{"type":"string","format":"date-time"}}}}},"paths":{"/api/organizations":{"get":{"tags":["Organizations"],"summary":"List organizations","description":"Returns all organizations the authenticated user belongs to.","responses":{"200":{"description":"List of organizations","content":{"application/json":{"schema":{"type":"object","properties":{"organizations":{"type":"array","items":{"$ref":"#/components/schemas/Organization"}}}}}}}}},"post":{"tags":["Organizations"],"summary":"Create organization","description":"Create a new organization. This is the first step for any new client integration.\nThe organization is the top-level container for all resources (projects, KBs, team, etc.).\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","slug"],"properties":{"name":{"type":"string","example":"Acme Corp"},"slug":{"type":"string","example":"acme-corp","description":"URL-friendly identifier (unique across platform)"},"tier":{"type":"string","enum":["startup","growth","enterprise"],"default":"growth"},"billingEmail":{"type":"string","format":"email"},"settings":{"type":"object","properties":{"chatModel":{"type":"string"},"maxMembers":{"type":"integer"},"maxProjects":{"type":"integer"},"maxStorage":{"type":"integer"}}}}}}}},"responses":{"201":{"description":"Organization created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}}}}},"/api/organizations/list":{"get":{"tags":["Organizations"],"summary":"List organizations (with active org context)","description":"Returns organizations with the currently active organization marked.","responses":{"200":{"description":"Organization list with current active org","content":{"application/json":{"schema":{"type":"object","properties":{"organizations":{"type":"array","items":{"$ref":"#/components/schemas/Organization"}},"currentOrganizationId":{"type":"string"}}}}}}}}},"/api/organizations/switch":{"post":{"tags":["Organizations"],"summary":"Switch active organization","description":"Set the active organization for the current user session.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["organizationId"],"properties":{"organizationId":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Active organization switched"}}}},"/api/organizations/{organizationId}":{"get":{"tags":["Organizations"],"summary":"Get organization details","description":"Returns full organization details including settings and connected services.","parameters":[{"$ref":"#/components/parameters/organizationId"}],"responses":{"200":{"description":"Organization details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Organization"}}}}}},"patch":{"tags":["Organizations"],"summary":"Update organization","description":"Update organization name, settings, or billing info.","parameters":[{"$ref":"#/components/parameters/organizationId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"billingEmail":{"type":"string"},"settings":{"type":"object"}}}}}},"responses":{"200":{"description":"Organization updated"}}}},"/api/organizations/{organizationId}/team":{"get":{"tags":["Organization Team"],"summary":"List team members","description":"Returns all members of the organization with their roles.","parameters":[{"$ref":"#/components/parameters/organizationId"}],"responses":{"200":{"description":"Team member list","content":{"application/json":{"schema":{"type":"object","properties":{"members":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["owner","admin","member","viewer"]},"joinedAt":{"type":"string","format":"date-time"}}}}}}}}}}},"post":{"tags":["Organization Team"],"summary":"Invite, remove, or update team member","description":"Manage team membership. Actions: invite, remove, update_role.\n","parameters":[{"$ref":"#/components/parameters/organizationId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["action"],"properties":{"action":{"type":"string","enum":["invite","remove","update_role"]},"email":{"type":"string","description":"Required for invite and remove"},"userId":{"type":"string","description":"Required for update_role"},"role":{"type":"string","enum":["admin","member","viewer"],"description":"Required for invite and update_role"}}}}}},"responses":{"200":{"description":"Action completed"}}}},"/api/organizations/{organizationId}/token-usage":{"get":{"tags":["Organizations"],"summary":"Get token usage summary","description":"Returns token usage summary and optional detailed records for the organization.","parameters":[{"$ref":"#/components/parameters/organizationId"},{"name":"includeRecords","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Token usage data","content":{"application/json":{"schema":{"type":"object","properties":{"totalInputTokens":{"type":"integer"},"totalOutputTokens":{"type":"integer"},"totalCost":{"type":"number"},"records":{"type":"array","items":{"type":"object"}}}}}}}}}},"/api/organizations/{organizationId}/token-usage/current":{"get":{"tags":["Organizations"],"summary":"Get current month token usage","description":"Returns token usage for the current billing period (dashboard widget).","parameters":[{"$ref":"#/components/parameters/organizationId"}],"responses":{"200":{"description":"Current month usage"}}}},"/api/organizations/{organizationId}/search":{"get":{"tags":["Organizations"],"summary":"Search organization knowledge base","description":"Search across the organization's company-wide knowledge base.","parameters":[{"$ref":"#/components/parameters/organizationId"},{"name":"q","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Search results"}}}},"/api/organizations/{organizationId}-prefs/custom-prompts":{"get":{"tags":["Organization Preferences"],"summary":"List custom prompts","description":"List all custom prompts configured for this organization.","parameters":[{"$ref":"#/components/parameters/organizationId"}],"responses":{"200":{"description":"Custom prompts list"}}},"post":{"tags":["Organization Preferences"],"summary":"Create custom prompt","parameters":[{"$ref":"#/components/parameters/organizationId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","content"],"properties":{"name":{"type":"string"},"content":{"type":"string"},"category":{"type":"string"}}}}}},"responses":{"201":{"description":"Custom prompt created"}}}},"/api/organizations/{organizationId}-prefs/model-preferences":{"get":{"tags":["Organization Preferences"],"summary":"Get model preferences","description":"Returns the organization's preferred AI models for different tasks.","parameters":[{"$ref":"#/components/parameters/organizationId"}],"responses":{"200":{"description":"Model preferences"}}},"put":{"tags":["Organization Preferences"],"summary":"Update model preferences","parameters":[{"$ref":"#/components/parameters/organizationId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"chatModel":{"type":"string"},"agentModel":{"type":"string"}}}}}},"responses":{"200":{"description":"Preferences updated"}}}},"/api/projects":{"get":{"tags":["Projects"],"summary":"List projects","description":"Returns all projects for the authenticated user's organization.\nProjects are scoped workspaces that group related work (RFP, QA, migration, etc.).\n","parameters":[{"name":"organizationId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter by organization (defaults to session org)"}],"responses":{"200":{"description":"Project list","content":{"application/json":{"schema":{"type":"object","properties":{"projects":{"type":"array","items":{"$ref":"#/components/schemas/Project"}}}}}}}}},"post":{"tags":["Projects"],"summary":"Create project","description":"Create a new project under an organization. Projects can be created from\ntemplates (RFP, migration, etc.) or as blank workspaces. Link knowledge bases\nto provide context for AI operations.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","organizationId"],"properties":{"name":{"type":"string","example":"Q1 2026 Government RFP Response"},"organizationId":{"type":"string","format":"uuid"},"description":{"type":"string"},"templateId":{"type":"string","description":"Optional template to initialize from"},"templateType":{"type":"string","enum":["rfp","migration","qa","blank"]},"knowledgeBaseIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Knowledge bases to link to this project"},"agentConfigs":{"type":"array","items":{"type":"object","properties":{"agentType":{"type":"string"},"enabled":{"type":"boolean"},"config":{"type":"object"}}}}}}}}},"responses":{"201":{"description":"Project created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}}}}},"/api/projects/{projectId}":{"get":{"tags":["Projects"],"summary":"Get project details","description":"Returns full project details including linked KBs, agent configs, and stats.","parameters":[{"$ref":"#/components/parameters/projectId"}],"responses":{"200":{"description":"Project details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Project"}}}}}},"patch":{"tags":["Projects"],"summary":"Update project","description":"Update project name, description, linked knowledge bases, agent configs, etc.\nUse this to link/unlink knowledge bases by updating `knowledgeBaseIds`.\n","parameters":[{"$ref":"#/components/parameters/projectId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"knowledgeBaseIds":{"type":"array","items":{"type":"string","format":"uuid"},"description":"Replace linked knowledge bases"},"agentConfigs":{"type":"array","items":{"type":"object"}},"status":{"type":"string","enum":["active","archived"]}}}}}},"responses":{"200":{"description":"Project updated"}}},"delete":{"tags":["Projects"],"summary":"Delete project","parameters":[{"$ref":"#/components/parameters/projectId"}],"responses":{"200":{"description":"Project deleted"}}}},"/api/projects/{projectId}/files":{"get":{"tags":["Project Files"],"summary":"List project files","description":"Returns all files uploaded to this project with their processing status.","parameters":[{"$ref":"#/components/parameters/projectId"}],"responses":{"200":{"description":"File list with processing status","content":{"application/json":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"type":"object","properties":{"fileId":{"type":"string"},"fileName":{"type":"string"},"status":{"type":"string","enum":["pending","processing","indexed","error"]},"uploadedAt":{"type":"string","format":"date-time"},"size":{"type":"integer"}}}}}}}}}}}},"/api/projects/{projectId}/files/reindex":{"post":{"tags":["Project Files"],"summary":"Reindex project files","description":"Trigger reindexing of all or specific files in the project.","parameters":[{"$ref":"#/components/parameters/projectId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"all":{"type":"boolean","default":false},"fileIds":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Reindexing triggered"}}}},"/api/projects/{projectId}/chat":{"post":{"tags":["Projects"],"summary":"Project chat","description":"Chat with the project's knowledge base using unified search.\nReturns AI-generated answers with source citations from linked KBs.\n","parameters":[{"$ref":"#/components/parameters/projectId"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["query"],"properties":{"query":{"type":"string","example":"What are the compliance requirements?"},"conversationHistory":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"200":{"description":"Chat response with sources"}}}},"/api/projects/{projectId}/indexing-status":{"get":{"tags":["Project Files"],"summary":"Get indexing status","description":"Returns the indexing status for all files in the project.","parameters":[{"$ref":"#/components/parameters/projectId"}],"responses":{"200":{"description":"Per-file indexing status"}}}},"/api/projects/{projectId}/master-context":{"get":{"tags":["Projects"],"summary":"Get project master context","description":"Returns the AI-generated master context for the project.","parameters":[{"$ref":"#/components/parameters/projectId"}],"responses":{"200":{"description":"Master context"}}},"put":{"tags":["Projects"],"summary":"Update project master context","parameters":[{"$ref":"#/components/parameters/projectId"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"masterContext":{"type":"string"}}}}}},"responses":{"200":{"description":"Master context updated"}}}},"/api/projects/{projectId}/generate-context":{"post":{"tags":["Projects"],"summary":"Generate master context","description":"AI-generate a master context from the project's linked knowledge bases.","parameters":[{"$ref":"#/components/parameters/projectId"}],"responses":{"200":{"description":"Context generation started"}}}},"/api/projects/{projectId}/agent-runs":{"get":{"tags":["Agent Runs"],"summary":"List project agent runs","description":"Returns all agent execution runs for this project.","parameters":[{"$ref":"#/components/parameters/projectId"},{"name":"limit","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"Agent run list"}}}},"/api/projects/{projectId}/duplicate":{"post":{"tags":["Projects"],"summary":"Duplicate project","description":"Create a copy of the project with all its configuration.","parameters":[{"$ref":"#/components/parameters/projectId"}],"responses":{"201":{"description":"Duplicated project"}}}},"/api/projects/{projectId}/executions/latest":{"get":{"tags":["Projects"],"summary":"Get latest execution","description":"Returns the most recent RFP execution and all agent outputs for this project.","parameters":[{"$ref":"#/components/parameters/projectId"}],"responses":{"200":{"description":"Latest execution with agent outputs"}}}},"/api/projects/{id}/analyze-content-types":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Content Type Analysis"],"summary":"Start content type analysis","description":"Triggers AI analysis of all indexed pages to recommend CMS content types\n(e.g., Drupal content types). Analyzes page structure, elements, and patterns\nto generate field mapping templates.\n\nThis is async - use the jobId to poll for results.\n","responses":{"200":{"description":"Analysis job started","content":{"application/json":{"schema":{"type":"object","properties":{"jobId":{"type":"string"},"status":{"type":"string"}}}}}}}}},"/api/projects/{id}/analyze-content-types/{jobId}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"jobId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Content Type Analysis"],"summary":"Get content type analysis status/results","description":"Polls the async content type analysis job for completion and results.","responses":{"200":{"description":"Analysis results with recommended content types and field mappings"}}}},"/api/projects/{id}/content-type-config":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Content Type Analysis"],"summary":"Get approved content type config","responses":{"200":{"description":"Content type configuration"}}},"post":{"tags":["Content Type Analysis"],"summary":"Save content type config","description":"Save the approved content type configuration for a migration project.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"contentTypes":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"machineName":{"type":"string"},"fields":{"type":"array","items":{"type":"object"}}}}}}}}}},"responses":{"200":{"description":"Config saved"}}}},"/api/projects/{id}/page-transformation-preview":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Page Transformation"],"summary":"Preview page transformation","description":"Shows how a page will look after applying content type field mappings.\nMaps existing page elements to CMS fields. No AI calls - uses\npre-computed templates from content type analysis.\n","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["fileId"],"properties":{"fileId":{"type":"string"},"contentTypeId":{"type":"string"}}}}}},"responses":{"200":{"description":"Transformation preview"}}}},"/api/projects/{id}/page-migration-config":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Page Transformation"],"summary":"Get page migration config","responses":{"200":{"description":"Page migration configuration"}}},"post":{"tags":["Page Transformation"],"summary":"Save page migration config","description":"Save per-page migration configurations (content type assignment, field overrides).","responses":{"200":{"description":"Config saved"}}}},"/api/projects/{id}/navigation-strategy":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Page Transformation"],"summary":"Get navigation strategy","description":"Returns the AI-generated or manually configured navigation tree for site migration.","responses":{"200":{"description":"Navigation tree structure"}}},"post":{"tags":["Page Transformation"],"summary":"Save navigation strategy","description":"Save the approved navigation tree structure.","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"tree":{"type":"array","description":"Navigation tree nodes"}}}}}},"responses":{"200":{"description":"Navigation saved"}}}},"/api/knowledge-bases":{"get":{"tags":["Knowledge Bases"],"summary":"List knowledge bases","description":"Returns all knowledge bases for the authenticated user's organization.","responses":{"200":{"description":"List of knowledge bases","content":{"application/json":{"schema":{"type":"object","properties":{"knowledgeBases":{"type":"array","items":{"$ref":"#/components/schemas/KnowledgeBase"}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Knowledge Bases"],"summary":"Create knowledge base","description":"Creates a new knowledge base. Files can be uploaded after creation.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeBaseCreate"}}}},"responses":{"201":{"description":"Knowledge base created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeBase"}}}}}}},"/api/knowledge-bases/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"tags":["Knowledge Bases"],"summary":"Get knowledge base","responses":{"200":{"description":"Knowledge base details","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeBase"}}}}}},"patch":{"tags":["Knowledge Bases"],"summary":"Update knowledge base","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"isPublic":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Updated knowledge base"}}},"delete":{"tags":["Knowledge Bases"],"summary":"Delete knowledge base","responses":{"200":{"description":"Knowledge base deleted"}}}},"/api/knowledge-bases/{id}/files":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Knowledge Base Files"],"summary":"List files in knowledge base","responses":{"200":{"description":"List of files","content":{"application/json":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"$ref":"#/components/schemas/FileUpload"}}}}}}}}},"post":{"tags":["Knowledge Base Files"],"summary":"Upload file to knowledge base","description":"Upload a file to be processed and indexed. Supported formats:\nPDF, DOCX, XLSX, PPTX, HTML, TXT, MD, images (PNG/JPG), and emails.\n\nThe file goes through the processing pipeline:\nExtract → Chunk → Embed → Index\n\nProcessing is asynchronous. Poll the file status or use webhooks.\n","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}}}}}},"responses":{"200":{"description":"File uploaded and processing started","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileUpload"}}}}}}},"/api/knowledge-bases/{id}/search":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Knowledge Base Search"],"summary":"Semantic search in knowledge base","description":"Performs semantic (vector) search across all indexed content in the knowledge base.\nUses hybrid search combining dense embeddings with keyword matching.\nResults include relevance scores and source metadata.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}}},"responses":{"200":{"description":"Search results","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchResult"}}}}}}},"/api/knowledge-bases/{id}/index":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Knowledge Base Files"],"summary":"Trigger knowledge base indexing","description":"Re-indexes all files in the knowledge base.","responses":{"200":{"description":"Indexing started"}}}},"/api/knowledge-bases/{id}/tools":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Voice Tools"],"summary":"List tools assigned to knowledge base","responses":{"200":{"description":"List of voice tools"}}},"post":{"tags":["Voice Tools"],"summary":"Create and assign tool to knowledge base","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceTool"}}}},"responses":{"201":{"description":"Tool created"}}}},"/api/knowledge-bases/{id}/share":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Knowledge Bases"],"summary":"List shares for knowledge base","responses":{"200":{"description":"List of organizations this KB is shared with"}}},"post":{"tags":["Knowledge Bases"],"summary":"Share knowledge base with organization","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["targetOrgId"],"properties":{"targetOrgId":{"type":"string"},"permission":{"type":"string","enum":["read","write"],"default":"read"}}}}}},"responses":{"200":{"description":"KB shared"}}}},"/api/public/kb/{kbId}":{"parameters":[{"name":"kbId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Knowledge Bases"],"summary":"Get public knowledge base","description":"Retrieve metadata for a public knowledge base (no auth required).","security":[],"responses":{"200":{"description":"Public KB metadata"}}}},"/api/public/kb/{kbId}/search":{"parameters":[{"name":"kbId","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Knowledge Base Search"],"summary":"Search public knowledge base","description":"Search a public knowledge base (no auth, rate-limited by IP).","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}}},"responses":{"200":{"description":"Search results"}}}},"/api/knowledge-bases/{id}/outbound-context/save":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Voice Context"],"summary":"Save outbound call context","description":"Save context/instructions specific to outbound calls for this KB.","responses":{"200":{"description":"Outbound context saved"}}}},"/api/knowledge-bases/{id}/files/{fileId}/preview":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fileId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Files"],"summary":"Get file preview URL","description":"Returns a signed URL or source URL for previewing a file.","responses":{"200":{"description":"Preview URL"}}}},"/api/knowledge-bases/{id}/files/{fileId}/html-proxy":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fileId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Files"],"summary":"Get HTML proxy for page preview","description":"Proxies an external web page with injected highlight scripts.\nUsed for iframe-based page preview with search result highlighting.\n","responses":{"200":{"description":"Proxied HTML content"}}}},"/api/pm/stories":{"post":{"tags":["PM Stories"],"summary":"Create a user story","description":"Create a new user story within a project. Stories follow INVEST criteria\nand serve as test basis per ISTQB methodology.\n","operationId":"createStory","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectId","organizationId","title"],"properties":{"projectId":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":3},"userStory":{"type":"string","description":"As a [role], I want [capability], so that [benefit]"},"description":{"type":"string"},"type":{"type":"string","enum":["feature","bug","task","spike","epic"],"default":"feature"},"priority":{"type":"string","enum":["critical","high","medium","low"],"default":"medium"},"acceptanceCriteria":{"type":"array","items":{"type":"object","properties":{"given":{"type":"string"},"when":{"type":"string"},"then":{"type":"string"}}}},"storyPoints":{"type":"integer","minimum":0,"maximum":100},"tags":{"type":"array","items":{"type":"string"}},"assignee":{"type":"string"},"sprintId":{"type":"string","format":"uuid"}}},"example":{"projectId":"550e8400-e29b-41d4-a716-446655440000","organizationId":"660e8400-e29b-41d4-a716-446655440000","title":"User login with email and password","userStory":"As a registered user, I want to log in with my email and password, so that I can access my account","type":"feature","priority":"high","acceptanceCriteria":[{"given":"a registered user on the login page","when":"they enter valid email and password and click Login","then":"they are redirected to the dashboard"}]}}}},"responses":{"201":{"description":"Story created"},"400":{"description":"Validation error"}}},"get":{"tags":["PM Stories"],"summary":"List stories for a project","operationId":"listStories","parameters":[{"name":"projectId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","schema":{"type":"string","enum":["backlog","ready","in_progress","in_review","testing","done","cancelled"]}},{"name":"assignee","in":"query","schema":{"type":"string"},"description":"Filter by assignee (email or user ID)"},{"name":"sprintId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Filter by sprint"}],"responses":{"200":{"description":"List of stories"}}}},"/api/pm/stories/{storyId}":{"get":{"tags":["PM Stories"],"summary":"Get story details","operationId":"getStory","parameters":[{"name":"storyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Story details"},"404":{"description":"Story not found"}}},"put":{"tags":["PM Stories"],"summary":"Update a story","operationId":"updateStory","parameters":[{"name":"storyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"status":{"type":"string","enum":["backlog","ready","in_progress","in_review","testing","done","cancelled"]},"priority":{"type":"string","enum":["critical","high","medium","low"]},"storyPoints":{"type":"integer"},"assignee":{"type":"string"}}}}}},"responses":{"200":{"description":"Updated story"}}},"delete":{"tags":["PM Stories"],"summary":"Delete a story","operationId":"deleteStory","parameters":[{"name":"storyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Story deleted"}}}},"/api/pm/stories/{storyId}/estimate":{"post":{"tags":["PM Estimation"],"summary":"AI story pointing","description":"Uses AI to estimate story points on a modified Fibonacci scale (1,2,3,5,8,13,21).\nConsiders complexity, risk factors, and effort breakdown (development, testing, integration).\n","operationId":"estimateStory","parameters":[{"name":"storyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"context":{"type":"string","description":"Additional context for estimation"}}}}}},"responses":{"200":{"description":"Estimation result with points, rationale, and risk analysis"}}}},"/api/pm/stories/{storyId}/generate-tests":{"post":{"tags":["PM Stories","QA Test Cases"],"summary":"Generate test cases from story","description":"Generates ISTQB-aligned test cases using the story as test basis.\nAcceptance criteria become test conditions. Generated test case IDs\nare automatically bound to the story.\n","operationId":"generateTestsFromStory","parameters":[{"name":"storyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"scope":{"type":"string","enum":["full","user-stories","api","security","performance"],"default":"user-stories"},"format":{"type":"string","enum":["standard","gherkin","bdd"],"default":"standard"},"maxTestCases":{"type":"integer","default":20}}}}}},"responses":{"200":{"description":"Generated test cases bound to the story"}}}},"/api/pm/stories/generate":{"post":{"tags":["PM Stories"],"summary":"AI-generate stories from requirements","description":"Provide requirements text and get well-structured user stories\nfollowing INVEST criteria. Optionally auto-save to a project.\n","operationId":"generateStories","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["requirements"],"properties":{"requirements":{"type":"string","minLength":10,"description":"Requirements text to generate stories from"},"projectId":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"maxStories":{"type":"integer","default":20},"autoSave":{"type":"boolean","default":false,"description":"Persist generated stories to the project"}}},"example":{"requirements":"The application needs user authentication with email/password, social login, password reset, and two-factor authentication.","maxStories":15}}}},"responses":{"200":{"description":"Generated user stories"}}}},"/api/pm/sprints":{"post":{"tags":["PM Sprints"],"summary":"Create a sprint","operationId":"createSprint","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectId","organizationId","name"],"properties":{"projectId":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"name":{"type":"string"},"goal":{"type":"string"},"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"},"durationWeeks":{"type":"integer","default":2},"velocity":{"type":"integer","description":"Team velocity in story points"}}}}}},"responses":{"201":{"description":"Sprint created"}}},"get":{"tags":["PM Sprints"],"summary":"List sprints for a project","operationId":"listSprints","parameters":[{"name":"projectId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"List of sprints"}}}},"/api/pm/sprints/{sprintId}":{"get":{"tags":["PM Sprints"],"summary":"Get sprint details","operationId":"getSprint","parameters":[{"name":"sprintId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Sprint details"}}},"put":{"tags":["PM Sprints"],"summary":"Update a sprint","operationId":"updateSprint","parameters":[{"name":"sprintId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"goal":{"type":"string"},"status":{"type":"string","enum":["planning","active","completed","cancelled"]},"storyIds":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Updated sprint"}}}},"/api/pm/sprints/{sprintId}/plan":{"post":{"tags":["PM Sprints"],"summary":"AI sprint planning","description":"AI selects and prioritizes stories for the sprint based on velocity,\npriority, dependencies, and risk. Optionally auto-assigns stories.\n","operationId":"planSprint","parameters":[{"name":"sprintId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"velocity":{"type":"integer","default":30,"description":"Team velocity in story points"},"autoAssign":{"type":"boolean","default":false,"description":"Auto-assign selected stories to this sprint"},"context":{"type":"string"}}}}}},"responses":{"200":{"description":"Sprint plan with selected stories"}}}},"/api/pm/docs/generate/user-manual":{"post":{"tags":["PM Documentation"],"summary":"Generate user manual","description":"Generate a comprehensive user manual from stories, test results,\nor direct content. Structured with overview, getting started,\nfeatures, troubleshooting, and FAQ sections.\n","operationId":"generateUserManual","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"projectId":{"type":"string","format":"uuid","description":"Pull completed stories from this project"},"title":{"type":"string","default":"User Manual"},"content":{"type":"string","description":"Additional content to include"},"stories":{"type":"array","description":"Inline stories to document","items":{"type":"object","properties":{"title":{"type":"string"},"userStory":{"type":"string"},"description":{"type":"string"}}}},"testResults":{"type":"string","description":"Test results summary for verified behaviors"}}},"example":{"title":"MyApp User Manual","stories":[{"title":"User Registration","userStory":"As a new user, I want to register an account","description":"Email/password registration with verification"}]}}}},"responses":{"200":{"description":"Generated user manual"}}}},"/api/pm/stories/{storyId}/sync-tests":{"post":{"tags":["PM Stories"],"summary":"Self-heal, sync test cases when story changes","description":"When a story's acceptance criteria or description changes, this\nendpoint analyzes the delta and recommends test case updates:\n- UPDATED: existing tests with changed expected results\n- ADDED: new tests for new acceptance criteria\n- REMOVED: obsolete tests for deleted criteria\n\nPass the previous version in the body for accurate diff analysis.\n","parameters":[{"name":"storyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"previousVersion":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"acceptanceCriteria":{"type":"array","items":{"type":"object","properties":{"given":{"type":"string"},"when":{"type":"string"},"then":{"type":"string"}}}}}}}}}}},"responses":{"200":{"description":"Test sync analysis with recommended changes"}}}},"/api/pm/risks/analyze":{"post":{"tags":["PM Risks"],"summary":"AI risk analysis (Rex Black methodology)","description":"Identify and score product risks from requirements or project stories\nusing Rex Black's risk-based testing methodology.\n\n**Scoring:** Likelihood (1-5) x Impact (1-5) = Risk Level (1-25)\n**Categories:** critical (20-25), high (12-19), medium (6-11), low (1-5)\n\nIncludes compliance gap analysis for FedRAMP, SOC 2, HIPAA, etc.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"requirements":{"type":"string","description":"Requirements text to analyze"},"projectId":{"type":"string","format":"uuid","description":"Or analyze existing project stories"},"organizationId":{"type":"string","format":"uuid"},"domain":{"type":"string","example":"government","description":"Industry domain for domain-specific risks"},"complianceFrameworks":{"type":"array","items":{"type":"string"},"example":["FedRAMP","SOC2"]}}}}}},"responses":{"200":{"description":"Risk analysis with scored matrix and test strategy"}}}},"/api/public/test-cases/extract-from-file":{"post":{"operationId":"publicTestCaseExtractFromFile","summary":"Extract requirements text from an uploaded file","description":"Accepts a file upload (PDF, DOCX, DOC, XLSX, XLS, CSV, TXT, MD) and\nreturns the extracted plain text suitable for pasting into the test\ncase generator. Limit: 10 MB per file, 30 uploads per hour per IP.\n","tags":["Public Test Case Generator"],"security":[],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"PDF, DOCX, DOC, XLSX, XLS, CSV, TXT, or MD file (≤10 MB)"}},"required":["file"]}}}},"responses":{"200":{"description":"Text extracted successfully","content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","description":"Extracted plain text from the file"},"fileName":{"type":"string"},"fileType":{"type":"string","enum":["pdf","docx","doc","xlsx","xls","csv","txt","md"]},"charCount":{"type":"integer"}}},"examples":{"pdf":{"summary":"PDF extraction","value":{"text":"1. Login Page\nAs a user, I want to log in with my email and password...","fileName":"requirements.pdf","fileType":"pdf","charCount":2415}}}}}},"400":{"description":"Invalid file (missing, wrong type, empty, or oversize)"},"429":{"description":"Rate limit exceeded (30 uploads/hour/IP)"}}}},"/api/public/test-cases/generate":{"post":{"operationId":"publicTestCaseGenerate","summary":"Generate test cases from requirements","description":"Generates ISTQB-aligned test cases enriched with the Rex Black training\nknowledge base. Two modes:\n\n* **`stream: false` (default)**, synchronous; returns the test cases in\n  the response body. Capped by CloudFront's 120-second timeout.\n* **`stream: true`**, dispatches to a background Lambda worker and\n  returns an `executionId` immediately. Subscribe via WebSocket to\n  receive `status`, `tool_call`, and `result` events.\n\nSupports five `mode` values: `agentic` (multi-turn Claude tool-use,\ndefault), `generate` (single-shot), `extract-requirements` (parse a\nrequirements doc into testable items), `gap-analysis`, and `fill-gaps`.\n\nRate limit: 20 generations per hour per IP.\n","tags":["Public Test Case Generator"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["requirements"],"properties":{"requirements":{"type":"string","minLength":20,"description":"User stories, acceptance criteria, or product description"},"mode":{"type":"string","enum":["agentic","generate","extract-requirements","gap-analysis","fill-gaps"],"default":"agentic"},"scope":{"type":"string","enum":["full","requirements","user-stories","api","accessibility","security","performance"],"default":"full"},"testTypes":{"type":"array","items":{"type":"string","enum":["functional","regression","integration","e2e","accessibility","security","performance","boundary","negative","smoke"]}},"priority":{"type":"string","enum":["all","critical","high","medium","low"],"default":"all"},"format":{"type":"string","enum":["standard","gherkin","bdd"],"default":"standard"},"maxTestCases":{"type":"integer","minimum":1,"maximum":500,"default":100},"context":{"type":"string","description":"Additional context (constraints, tech stack, etc.)"},"stream":{"type":"boolean","default":false,"description":"When true, dispatch to background worker and return executionId"},"existingTestCases":{"type":"array","description":"For mode=gap-analysis / fill-gaps","items":{"type":"object"}},"gaps":{"type":"array","description":"For mode=fill-gaps","items":{"type":"object"}},"uploadedContent":{"type":"string"},"uploadedFileName":{"type":"string"},"userKbIds":{"type":"array","items":{"type":"string"}},"codeContent":{"type":"string"},"codeLanguage":{"type":"string"},"sessionId":{"type":"string","description":"Reuse an existing session; otherwise a new session is created"},"userEmail":{"type":"string","format":"email"}}},"examples":{"agenticStream":{"summary":"Agentic mode with WebSocket streaming","value":{"requirements":"User can sign up with email + password, must verify email before logging in.","mode":"agentic","stream":true,"maxTestCases":30,"userEmail":"qa-lead@acme.com"}},"syncGenerate":{"summary":"Synchronous single-shot generation","value":{"requirements":"Checkout flow: cart → address → payment → confirmation","mode":"generate","scope":"full","maxTestCases":20}}}}}},"responses":{"200":{"description":"Result depends on `stream`. `stream: true` returns an executionId\nfor WebSocket subscription. `stream: false` returns the test cases\ninline.\n","content":{"application/json":{"schema":{"oneOf":[{"type":"object","description":"Streaming response, subscribe to WebSocket","properties":{"executionId":{"type":"string"},"sessionId":{"type":"string"},"message":{"type":"string"}}},{"type":"object","description":"Synchronous response, test cases inline","properties":{"success":{"type":"boolean"},"testCases":{"type":"array","items":{"$ref":"#/components/schemas/PublicTestCase"}},"summary":{"type":"object","properties":{"total":{"type":"integer"},"byPriority":{"type":"object"},"byType":{"type":"object"}}},"sessionId":{"type":"string"}}}]}}}},"400":{"description":"Validation failed (e.g. requirements <20 chars)"},"429":{"description":"Rate limit exceeded (20 generations/hour/IP)"},"500":{"description":"Generation failed"}}}},"/api/public/test-cases/export":{"post":{"operationId":"publicTestCaseExport","summary":"Export test cases to Jira/TestRail/Azure/CSV/Gherkin/JSON","description":"Renders an array of test cases into one of six deliverable formats and\nreturns it as a downloadable file. Use the `Content-Disposition` header\nto obtain the filename. Rate limit: 50 exports per hour per IP.\n","tags":["Public Test Case Export"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["testCases","format"],"properties":{"testCases":{"type":"array","items":{"$ref":"#/components/schemas/PublicTestCase"}},"format":{"type":"string","enum":["csv","gherkin","json","jira-xray","testrail","azure-devops"]},"projectName":{"type":"string","default":"GoOmni-Generated-Tests"}}}}}},"responses":{"200":{"description":"Export file (binary)","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}},"headers":{"Content-Disposition":{"schema":{"type":"string","example":"attachment; filename=\"test-cases.csv\""}}}},"400":{"description":"Invalid format or test cases"},"429":{"description":"Rate limit exceeded (50 exports/hour/IP)"}}}},"/api/public/test-cases/sessions":{"get":{"operationId":"publicListSessions","summary":"List generation sessions for an email","description":"Returns up to 20 most recent sessions for a given email address.","tags":["Public Test Sessions"],"security":[],"parameters":[{"name":"email","in":"query","required":true,"schema":{"type":"string","format":"email"}}],"responses":{"200":{"description":"Sessions list","content":{"application/json":{"schema":{"type":"object","properties":{"sessions":{"type":"array","items":{"type":"object","properties":{"sessionId":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"totalTestCases":{"type":"integer"},"turnCount":{"type":"integer"},"createdAt":{"type":"string"},"updatedAt":{"type":"string"}}}}}}}}},"400":{"description":"Missing email parameter"}}},"post":{"operationId":"publicCreateSession","summary":"Create a generation session","description":"Pre-creates an empty session you can later attach generations and edits to.","tags":["Public Test Sessions"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","requirements"],"properties":{"title":{"type":"string","minLength":1,"maxLength":200},"requirements":{"type":"string","minLength":20},"userEmail":{"type":"string","format":"email"},"scope":{"type":"string"},"format":{"type":"string"},"maxTestCases":{"type":"integer"},"uploadedFileName":{"type":"string"}}}}}},"responses":{"200":{"description":"Session created","content":{"application/json":{"schema":{"type":"object","properties":{"sessionId":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"createdAt":{"type":"string"}}}}}}}}},"/api/public/test-cases/sessions/{sessionId}":{"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"operationId":"publicGetSession","summary":"Get full session (requirements, conversation, test cases, events)","tags":["Public Test Sessions"],"security":[],"responses":{"200":{"description":"Session detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicSessionDetail"}}}},"404":{"description":"Session not found"}}},"post":{"operationId":"publicRefineSession","summary":"Refine the session with a follow-up message (multi-turn)","description":"Adds a user turn to the conversation and dispatches a refinement run.\nReturns an `executionId`, subscribe via WebSocket for streaming events.\n","tags":["Public Test Sessions"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string","minLength":5,"description":"Follow-up instruction (e.g. \"Add 5 more negative cases for password reset\")"},"scope":{"type":"string"},"format":{"type":"string"},"maxTestCases":{"type":"integer"}}}}}},"responses":{"200":{"description":"Refinement dispatched","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"executionId":{"type":"string"},"sessionId":{"type":"string"},"message":{"type":"string"}}}}}},"400":{"description":"Validation failed"},"404":{"description":"Session not found"}}},"patch":{"operationId":"publicPatchSessionTestCases","summary":"Replace the session's test cases (manual edits)","description":"Persists inline edits made in the UI (title, description, steps, priority,\ntags). The full test cases array is replaced atomically, call this from\na debounced autosave loop.\n","tags":["Public Test Sessions"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["testCases"],"properties":{"testCases":{"type":"array","maxItems":500,"items":{"$ref":"#/components/schemas/PublicTestCase"}}}}}}},"responses":{"200":{"description":"Test cases replaced","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"sessionId":{"type":"string"},"testCaseCount":{"type":"integer"},"updatedAt":{"type":"string"}}}}}},"404":{"description":"Session not found"}}}},"/api/public/test-cases/execute":{"post":{"operationId":"publicExecuteTestCases","summary":"Dispatch a hosted browser run for selected test cases","description":"Spins up Headless Chromium in AWS Lambda, navigates to your `config.url`,\nand runs each selected test case. Each prose step is interpreted by Claude\ninto typed browser actions (`goto`, `click`, `fill`, `wait_for_selector`,\n`assert_text`, etc.), executed, and verified. Each step is captured as a\nPNG screenshot and uploaded to S3.\n\nReturns immediately with an `executionId`. Subscribe via WebSocket\n(`{action:\"subscribe\", executionId}`) to receive `execution_start`,\n`case_start`, `step_start`, `step_complete`, `case_complete`, and\n`execution_complete` events. When the run completes, fetch\n`GET /api/public/test-cases/executions/{executionId}` for signed evidence URLs.\n\n**Free-tier limit:** 5 executions per hour per email.\n**Per-case timeout:** 240s. **Per-step timeout:** 30s.\n","tags":["Public Hosted Execution"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sessionId","testCaseIds","config"],"properties":{"sessionId":{"type":"string"},"testCaseIds":{"type":"array","minItems":1,"maxItems":100,"items":{"type":"string"},"description":"IDs of cases (within the session) to execute"},"testType":{"type":"string","enum":["web","rest_api","soap_api","graphql","a11y","perf"],"default":"web","description":"Currently only `web` is implemented. The other test types are\nreserved by the Executor abstraction and return 501 until their\nexecutors ship.\n"},"config":{"type":"object","description":"Polymorphic, depends on `testType`. For `web` see properties below.","properties":{"url":{"type":"string","format":"uri"},"browser":{"type":"string","enum":["chromium","firefox","webkit"],"default":"chromium"},"viewport":{"type":"object","properties":{"width":{"type":"integer"},"height":{"type":"integer"}}}},"required":["url"]},"parallel":{"type":"boolean","default":false,"description":"Reserved, currently sequential"},"userEmail":{"type":"string","format":"email","description":"Used for free-tier rate limiting (5/hour/email)"}}},"examples":{"singleCase":{"summary":"Run one case against a target URL","value":{"sessionId":"tcg-1730000000000-abc123","testCaseIds":["TC-001"],"testType":"web","config":{"url":"https://app.example.com","browser":"chromium"},"userEmail":"qa-lead@acme.com"}},"bulkRun":{"summary":"Run a smoke suite","value":{"sessionId":"tcg-1730000000000-abc123","testCaseIds":["TC-001","TC-002","TC-003","TC-007"],"testType":"web","config":{"url":"https://staging.example.com","browser":"chromium","viewport":{"width":1440,"height":900}},"userEmail":"qa-lead@acme.com"}}}}}},"responses":{"200":{"description":"Execution dispatched","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"executionId":{"type":"string"},"sessionId":{"type":"string"},"testType":{"type":"string"},"totalCases":{"type":"integer"},"missingTestCases":{"type":"array","items":{"type":"string"},"description":"IDs that weren't found in the session"},"message":{"type":"string"}}},"example":{"success":true,"executionId":"f15c68f0-b7ed-4767-b58e-c6f3de97ee18","sessionId":"tcg-1730000000000-abc123","testType":"web","totalCases":1,"message":"Execution dispatched. Subscribe to executionId via WebSocket for real-time updates."}}}},"400":{"description":"Validation failed (no matching test cases, bad config, etc.)"},"404":{"description":"Session not found"},"429":{"description":"Free-tier rate limit exceeded (5 executions/hour/email)"},"501":{"description":"Executor for the requested testType is not yet available"},"502":{"description":"Worker dispatch failed"}}}},"/api/public/test-cases/executions/{executionId}":{"parameters":[{"name":"executionId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"operationId":"publicGetExecution","summary":"Get execution detail with signed evidence URLs","description":"Returns the execution metadata, per-test-case results, and pre-signed S3\nURLs (1-hour TTL) for video, screenshots, console logs, network HAR, and\nmanifest/timeline JSON.\n","tags":["Public Hosted Execution"],"security":[],"responses":{"200":{"description":"Execution detail","content":{"application/json":{"schema":{"type":"object","properties":{"execution":{"type":"object","properties":{"executionId":{"type":"string"},"sessionId":{"type":"string"},"testType":{"type":"string","enum":["web","rest_api","soap_api","graphql","a11y","perf"]},"status":{"type":"string","enum":["queued","running","passed","failed","partial","error","cancelled"]},"totalCases":{"type":"integer"},"passedCount":{"type":"integer"},"failedCount":{"type":"integer"},"skippedCount":{"type":"integer"},"errorCount":{"type":"integer"},"browser":{"type":"string"},"baseUrl":{"type":"string"},"targetConfig":{"type":"object"},"manifestUrl":{"type":"string","description":"Signed URL to manifest.json (1h TTL)"},"timelineUrl":{"type":"string","description":"Signed URL to timeline.json (1h TTL)"},"queuedAt":{"type":"string","format":"date-time"},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"durationMs":{"type":"integer"},"errorMessage":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}},"cases":{"type":"array","items":{"type":"object","properties":{"testCaseId":{"type":"string"},"status":{"type":"string","enum":["passed","failed","skipped","error"]},"durationMs":{"type":"integer"},"stepResults":{"type":"array","items":{"$ref":"#/components/schemas/PublicStepResult"}},"assertionsTotal":{"type":"integer"},"assertionsPassed":{"type":"integer"},"assertionsFailed":{"type":"integer"},"errorMessage":{"type":"string"},"failedStep":{"type":"integer"},"videoUrl":{"type":"string","description":"Signed URL (1h TTL), null if video capture is off"},"consoleLogUrl":{"type":"string"},"networkHarUrl":{"type":"string"},"screenshotUrls":{"type":"array","items":{"type":"string"},"description":"Per-step PNG signed URLs (1h TTL)"},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"}}}}}}}}},"404":{"description":"Execution not found"}}}},"/api/public/test-cases/sessions/{sessionId}/executions":{"parameters":[{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":20,"maximum":100}}],"get":{"operationId":"publicListSessionExecutions","summary":"List past hosted execution runs for a session","description":"Returns lightweight metadata for each prior run (status, counts, browser,\nbaseUrl, durationMs). Used by the execution-history panel on the public\npage. For the full result of a specific run, call\n`GET /api/public/test-cases/executions/{executionId}`.\n","tags":["Public Hosted Execution"],"security":[],"responses":{"200":{"description":"Execution history","content":{"application/json":{"schema":{"type":"object","properties":{"executions":{"type":"array","items":{"type":"object","properties":{"executionId":{"type":"string"},"testType":{"type":"string"},"status":{"type":"string"},"totalCases":{"type":"integer"},"passedCount":{"type":"integer"},"failedCount":{"type":"integer"},"skippedCount":{"type":"integer"},"errorCount":{"type":"integer"},"durationMs":{"type":"integer"},"parallel":{"type":"boolean"},"browser":{"type":"string"},"baseUrl":{"type":"string"},"queuedAt":{"type":"string","format":"date-time"},"startedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}}}}},"/api/qa/setup":{"get":{"tags":["QA Setup"],"summary":"QA readiness check, shows quick-start and advanced paths","description":"Returns two paths to test case generation:\n\n**Quick Start (zero setup):** POST requirements text directly to `/api/qa/test-cases/generate`.\nNo organization, project, or knowledge base needed.\n\n**Advanced:** Full project + knowledge base setup for richer context,\nsemantic search over indexed documents, and persistent test artifacts.\n\nMethodology: ISTQB CTFL with EP, BVA, Decision Tables, State Transition, Use Case testing.\n","parameters":[{"name":"organizationId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Organization ID (defaults to session org)"},{"name":"projectId","in":"query","schema":{"type":"string","format":"uuid"},"description":"Project ID to check advanced setup for"}],"responses":{"200":{"description":"Setup status with quick-start example and advanced readiness","content":{"application/json":{"schema":{"type":"object","properties":{"quickStart":{"type":"object","properties":{"ready":{"type":"boolean","example":true},"description":{"type":"string"},"example":{"type":"object"}}},"advancedSetup":{"type":"object","properties":{"ready":{"type":"boolean"},"steps":{"type":"array","items":{"type":"object"}}}},"methodology":{"type":"string","example":"ISTQB CTFL, EP, BVA, Decision Tables, State Transition, Use Case Testing"},"capabilities":{"type":"object"}}}}}}}}},"/api/qa/test-cases":{"get":{"tags":["QA Test Cases"],"summary":"List persisted test cases for a project or story","description":"Retrieve stored test cases. Generated test cases are auto-persisted\nwhen projectId and organizationId are provided during generation.\nFilter by project (required) and optionally by story.\n","operationId":"listTestCases","parameters":[{"name":"projectId","in":"query","required":true,"schema":{"type":"string","format":"uuid"},"description":"Project to list test cases for"},{"name":"storyId","in":"query","schema":{"type":"string"},"description":"Filter to test cases linked to this story"}],"responses":{"200":{"description":"List of test cases","content":{"application/json":{"schema":{"type":"object","properties":{"testCases":{"type":"array","items":{"type":"object","properties":{"testCaseId":{"type":"string"},"title":{"type":"string"},"description":{"type":"string"},"priority":{"type":"string"},"type":{"type":"string"},"status":{"type":"string"},"steps":{"type":"array","items":{"type":"object","properties":{"stepNumber":{"type":"integer"},"action":{"type":"string"},"expectedResult":{"type":"string"}}}},"storyId":{"type":"string"},"createdAt":{"type":"string"}}}},"total":{"type":"integer"},"projectId":{"type":"string"}}}}}}}},"post":{"tags":["QA Test Cases"],"summary":"Create a test case manually","description":"Create a single test case manually (not AI-generated).\nLinked to a project and optionally to a story.\n","operationId":"createTestCase","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectId","organizationId","title"],"properties":{"projectId":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"title":{"type":"string","minLength":3},"description":{"type":"string"},"preconditions":{"type":"string"},"priority":{"type":"string","enum":["critical","high","medium","low"]},"type":{"type":"string","enum":["functional","security","performance","usability","api","integration","regression","smoke"]},"steps":{"type":"array","items":{"type":"object","properties":{"stepNumber":{"type":"integer"},"action":{"type":"string"},"expectedResult":{"type":"string"},"testData":{"type":"string"}}}},"storyId":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"Test case created"}}}},"/api/qa/test-cases/generate":{"post":{"tags":["QA Test Cases"],"summary":"Generate ISTQB-aligned test cases","description":"Generate structured test cases using ISTQB methodology.\n\n**Three ways to provide input (simplest first):**\n1. `requirements`, paste your requirements text directly (no setup needed)\n2. `projectId`, uses the project's linked knowledge base\n3. `knowledgeBaseId`, searches a specific indexed KB\n\nAll three can be combined for richer context.\n\n**ISTQB Design Techniques Applied:**\n- Equivalence Partitioning (EP)\n- Boundary Value Analysis (BVA)\n- Decision Table Testing\n- State Transition Testing\n- Use Case Testing\n\n**Export formats:** JSON, CSV, Gherkin, Jira Xray, TestRail, Azure DevOps\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"requirements":{"type":"string","description":"Requirements text, the simplest input, no project or KB needed","example":"REQ-001: The system shall allow users to register with email and password. Password must be at least 8 characters with uppercase, lowercase, number, and special character."},"projectId":{"type":"string","format":"uuid","description":"Optional, project with linked knowledge bases"},"knowledgeBaseId":{"type":"string","format":"uuid","description":"Optional, specific KB to search for requirements"},"scope":{"type":"string","enum":["full","requirements","user-stories","api","accessibility","security","performance"],"default":"full"},"testTypes":{"type":"array","items":{"type":"string","enum":["functional","regression","integration","e2e","accessibility","security","performance","boundary","negative","smoke"]}},"priority":{"type":"string","enum":["all","critical","high","medium","low"],"default":"all"},"format":{"type":"string","enum":["standard","gherkin","bdd"],"default":"standard"},"maxTestCases":{"type":"integer","minimum":1,"maximum":500,"default":50},"context":{"type":"string","description":"Additional context about the system under test"},"includeTraceability":{"type":"boolean","default":true}}},"examples":{"directText":{"summary":"Quick start, just paste requirements","value":{"requirements":"The system shall allow users to register with email and password. Failed login attempts are limited to 5 per 15-minute window.","scope":"full","maxTestCases":20}},"withProject":{"summary":"Advanced, with project and KB","value":{"projectId":"550e8400-e29b-41d4-a716-446655440000","scope":"full","format":"gherkin","maxTestCases":50}}}}}},"responses":{"200":{"description":"Generated test cases with ISTQB metadata","content":{"application/json":{"schema":{"type":"object","properties":{"testCases":{"type":"array","items":{"$ref":"#/components/schemas/TestCase"}},"summary":{"type":"object","properties":{"total":{"type":"integer"},"byPriority":{"type":"object"},"byType":{"type":"object"},"byLevel":{"type":"object"},"byTechnique":{"type":"object"},"coverage":{"type":"string"},"riskAssessment":{"type":"string"}}},"metadata":{"type":"object","properties":{"methodology":{"type":"string","example":"ISTQB CTFL"},"generatedAt":{"type":"string","format":"date-time"}}},"export":{"type":"object","description":"Instructions for exporting in different formats"}}}}}},"422":{"description":"No requirements provided, include requirements text, projectId, or knowledgeBaseId"}}}},"/api/qa/test-cases/export-scripts":{"post":{"tags":["QA Test Scripts"],"summary":"Export as runnable Playwright/Cypress/Selenium scripts","description":"Generate REAL, RUNNABLE test automation scripts from test cases.\nOutput files can be saved directly into your repo and executed.\n\n**Supported frameworks:**\n- Playwright (TypeScript/JavaScript)\n- Cypress (TypeScript/JavaScript)\n- Selenium (Python/Java)\n- Puppeteer (TypeScript/JavaScript)\n\n**Includes:**\n- Complete test files with imports, assertions, and proper structure\n- Page Object classes (optional)\n- Helper utilities (login, data setup)\n- Framework config file (playwright.config.ts, cypress.config.ts, etc.)\n- package.json with correct dependencies\n- README with run instructions\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["testCases","baseUrl"],"properties":{"testCases":{"type":"array","items":{"type":"object","required":["id","title","steps","expectedResult"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"steps":{"type":"array","items":{"type":"object","properties":{"stepNumber":{"type":"integer"},"action":{"type":"string"},"expectedResult":{"type":"string"}}}},"expectedResult":{"type":"string"}}}},"framework":{"type":"string","enum":["playwright","cypress","selenium-python","selenium-java","puppeteer"],"default":"playwright"},"language":{"type":"string","enum":["typescript","javascript","python","java"],"default":"typescript"},"baseUrl":{"type":"string","format":"uri","description":"Base URL of the application under test"},"projectName":{"type":"string","default":"tests"},"includePageObjects":{"type":"boolean","default":true},"includeHelpers":{"type":"boolean","default":true}}}}}},"responses":{"200":{"description":"Generated test scripts with file tree","content":{"application/json":{"schema":{"type":"object","properties":{"scripts":{"type":"array","items":{"type":"object","properties":{"filename":{"type":"string","example":"login.spec.ts"},"content":{"type":"string"},"testCount":{"type":"integer"}}}},"pageObjects":{"type":"array","items":{"type":"object","properties":{"filename":{"type":"string"},"content":{"type":"string"}}}},"config":{"type":"object","properties":{"filename":{"type":"string"},"content":{"type":"string"}}},"fileTree":{"type":"array","items":{"type":"string"}},"readme":{"type":"string"}}}}}}}}},"/api/qa/test-cases/export":{"post":{"tags":["QA Test Cases"],"summary":"Export test cases in tool-compatible formats","description":"Takes generated test cases and exports them in formats compatible\nwith major test management tools.\n\n**Supported Formats:**\n- `json`, Standard JSON with full metadata\n- `csv`, Spreadsheet-compatible CSV\n- `gherkin`, Cucumber/BDD .feature file format\n- `jira-xray`, Jira Xray test case import format\n- `testrail`, TestRail API import format\n- `azure-devops`, Azure DevOps Test Case work items\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["testCases","format"],"properties":{"testCases":{"type":"array","items":{"$ref":"#/components/schemas/TestCase"},"description":"Test cases from /generate response"},"format":{"type":"string","enum":["json","csv","gherkin","jira-xray","testrail","azure-devops"]},"projectName":{"type":"string","description":"Project name for file naming"}}}}}},"responses":{"200":{"description":"Exported file (Content-Disposition attachment)","content":{"application/json":{"schema":{"type":"object"}},"text/csv":{"schema":{"type":"string"}},"text/plain":{"schema":{"type":"string"}}}}}}},"/api/qa/requirements/extract":{"post":{"tags":["QA Requirements"],"summary":"Extract testable requirements from text or KB","description":"Analyzes content to extract structured, testable requirements\nusing ISTQB requirement analysis standards.\n\n**Two ways to provide input:**\n1. `content`, paste your requirements/spec text directly (no KB needed)\n2. `knowledgeBaseId` + `organizationId`, search an indexed KB\n\nBoth can be combined.\n\nEach requirement includes testability assessment, suggested ISTQB\ndesign technique, and acceptance criteria in Given/When/Then format.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"content":{"type":"string","description":"Requirements text, the simplest input, no KB needed","example":"The checkout shall support Visa, Mastercard, and PayPal. All payment data must be PCI-DSS compliant."},"knowledgeBaseId":{"type":"string","format":"uuid","description":"Optional, KB with indexed requirements documents"},"organizationId":{"type":"string","format":"uuid","description":"Required when using knowledgeBaseId"},"scope":{"type":"string","enum":["all","functional","non-functional","security","performance","accessibility"],"default":"all"},"includeTestability":{"type":"boolean","default":true}}},"examples":{"directText":{"summary":"Quick, paste requirements text","value":{"content":"The system shall allow users to register with email and password. Failed attempts limited to 5 per 15 minutes.","scope":"all"}},"withKB":{"summary":"From indexed knowledge base","value":{"knowledgeBaseId":"550e8400-e29b-41d4-a716-446655440000","organizationId":"660e8400-e29b-41d4-a716-446655440000","scope":"functional"}}}}}},"responses":{"200":{"description":"Extracted requirements with ISTQB analysis","content":{"application/json":{"schema":{"type":"object","properties":{"requirements":{"type":"array","items":{"$ref":"#/components/schemas/Requirement"}},"summary":{"type":"object","properties":{"total":{"type":"integer"},"byCategory":{"type":"object"},"byTestability":{"type":"object"},"gaps":{"type":"array","items":{"type":"string"}},"recommendations":{"type":"array","items":{"type":"string"}}}},"nextStep":{"type":"object","description":"How to use these requirements for test generation"}}}}}},"422":{"description":"No content provided, include content text or knowledgeBaseId"}}}},"/api/qa/test-execution/run":{"post":{"tags":["QA Test Execution"],"summary":"Execute test cases in a real browser (Puppeteer/Chromium)","description":"**Real browser execution** against your live URL.\n\nLaunches a headless Chromium browser, navigates to the target URL,\nand executes each test step by translating natural-language actions\ninto real browser interactions (click, type, assert, scroll, etc.).\n\n**Features:**\n- Real Puppeteer-based browser execution\n- **Parallel execution**, up to 10 browsers simultaneously\n- **Self-healing selectors**, AI auto-fixes broken CSS selectors at runtime\n- Screenshot capture at each step\n- Console error collection\n- Automatic defect creation for failed tests\n- Full traceability to stories and sprints\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectId","organizationId","targetUrl","testCases"],"properties":{"projectId":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"name":{"type":"string"},"targetUrl":{"type":"string","format":"uri","description":"URL of the application under test (REQUIRED for browser execution)"},"environment":{"type":"string","enum":["development","staging","production"],"default":"staging"},"testCases":{"type":"array","minItems":1,"items":{"type":"object","required":["id","title","steps","expectedResult"],"properties":{"id":{"type":"string"},"title":{"type":"string"},"steps":{"type":"array","items":{"type":"object","properties":{"stepNumber":{"type":"integer"},"action":{"type":"string"},"expectedResult":{"type":"string"},"testData":{"type":"string"}}}},"preconditions":{"type":"array","items":{"type":"string"}},"expectedResult":{"type":"string"}}}},"storyId":{"type":"string","format":"uuid"},"sprintId":{"type":"string","format":"uuid"},"autoCreateDefects":{"type":"boolean","default":true,"description":"Automatically create defect tickets for failed/errored tests"},"parallel":{"type":"integer","minimum":1,"maximum":10,"default":3,"description":"Number of browser instances to run in parallel"}}}}}},"responses":{"200":{"description":"Execution results with real browser pass/fail and step-level detail","content":{"application/json":{"schema":{"type":"object","properties":{"executionId":{"type":"string"},"status":{"type":"string"},"engine":{"type":"string","example":"puppeteer-browser"},"results":{"type":"array","items":{"type":"object","properties":{"testCaseId":{"type":"string"},"result":{"type":"string","enum":["pass","fail","error","skip","blocked"]},"steps":{"type":"array","items":{"type":"object","properties":{"stepNumber":{"type":"integer"},"status":{"type":"string"},"expected":{"type":"string"},"actual":{"type":"string"},"durationMs":{"type":"integer"},"hasScreenshot":{"type":"boolean"}}}}}}},"defectsCreated":{"type":"array","items":{"type":"object","properties":{"defectId":{"type":"string"},"testCaseId":{"type":"string"},"title":{"type":"string"}}}}}}}}}}}},"/api/qa/test-execution/{executionId}/status":{"get":{"tags":["QA Test Execution"],"summary":"Get execution status","parameters":[{"name":"executionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Current execution status and summary"}}}},"/api/qa/test-execution/{executionId}/results":{"get":{"tags":["QA Test Execution"],"summary":"Get detailed execution results","parameters":[{"name":"executionId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Detailed results for each test case"},"202":{"description":"Execution still in progress"}}}},"/api/qa/knowledge/query":{"post":{"tags":["QA Knowledge"],"summary":"Query QA training materials and ISTQB knowledge","description":"Ask questions about QA definitions, best practices, standards,\nmethodologies, and tools. Uses the organization's training\nmaterials as the primary knowledge source.\n\n**Categories:**\n- `definition`, What is X? Terminology and definitions\n- `best-practice`, Best approaches and recommended patterns\n- `standard`, ISTQB, ISO 29119, and other standards\n- `methodology`, Testing methodologies and frameworks\n- `tool`, Tool recommendations and integration guidance\n- `general`, General QA questions\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["question","organizationId"],"properties":{"question":{"type":"string","minLength":3,"example":"What is boundary value analysis?"},"knowledgeBaseId":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"category":{"type":"string","enum":["definition","best-practice","standard","methodology","tool","general"],"default":"general"},"includeSourceCitations":{"type":"boolean","default":true}}}}}},"responses":{"200":{"description":"QA knowledge answer with sources","content":{"application/json":{"schema":{"type":"object","properties":{"answer":{"type":"string"},"confidence":{"type":"string","enum":["high","medium","low"]},"sources":{"type":"array","items":{"type":"object"}},"relatedTopics":{"type":"array","items":{"type":"string"}}}}}}}}}},"/api/qa/defects":{"post":{"tags":["QA Defects"],"summary":"Create a defect manually","description":"Create a bug/defect ticket linked to stories, test cases, and executions.\nDefects are also auto-created when browser tests fail.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectId","organizationId","title"],"properties":{"projectId":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"title":{"type":"string"},"description":{"type":"string"},"stepsToReproduce":{"type":"string"},"severity":{"type":"string","enum":["critical","major","minor","trivial"]},"priority":{"type":"string","enum":["critical","high","medium","low"]},"storyId":{"type":"string","format":"uuid"},"testCaseId":{"type":"string"},"executionId":{"type":"string","format":"uuid"},"environment":{"type":"string"},"assignee":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"Defect created"}}},"get":{"tags":["QA Defects"],"summary":"List defects for a project","parameters":[{"name":"projectId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"List of defects"}}}},"/api/qa/defects/{defectId}":{"get":{"tags":["QA Defects"],"summary":"Get defect details","parameters":[{"name":"defectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Defect details with traceability links"}}},"put":{"tags":["QA Defects"],"summary":"Update defect (status, assignee, resolution)","parameters":[{"name":"defectId","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["open","in_progress","fixed","verified","closed","reopened","deferred"]},"severity":{"type":"string","enum":["critical","major","minor","trivial"]},"priority":{"type":"string","enum":["critical","high","medium","low"]},"assignee":{"type":"string"},"resolution":{"type":"string"}}}}}},"responses":{"200":{"description":"Updated defect"}}},"delete":{"tags":["QA Defects"],"summary":"Delete a defect","parameters":[{"name":"defectId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Defect deleted"}}}},"/api/qa/traceability":{"get":{"tags":["QA Traceability"],"summary":"Full project traceability matrix (live data)","description":"Returns the complete traceability chain from your project's live data:\nStory -> Test Cases -> Execution Results -> Defects\n\nIncludes coverage statistics, pass rates, and open defect counts.\nEssential for government compliance audits and ISTQB process improvement.\n","parameters":[{"name":"projectId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Live traceability matrix with coverage summary","content":{"application/json":{"schema":{"type":"object","properties":{"matrix":{"type":"array","items":{"type":"object","properties":{"storyId":{"type":"string"},"storyTitle":{"type":"string"},"testCaseCount":{"type":"integer"},"coverageStatus":{"type":"string","enum":["full","partial","none"]},"lastExecutionResult":{"type":"string"},"defects":{"type":"array","items":{"type":"object"}}}}},"summary":{"type":"object","properties":{"totalStories":{"type":"integer"},"coveragePercent":{"type":"integer"},"passRate":{"type":"integer"},"openDefects":{"type":"integer"}}}}}}}}}}},"/api/qa/bdd":{"post":{"tags":["QA BDD"],"summary":"Generate executable BDD/Gherkin feature files","description":"First-class BDD generation, produces complete .feature files with\nstep definitions, data tables, and scenario outlines.\n\n**Supported frameworks:** Cucumber, Behave, SpecFlow, Cypress-Cucumber, Playwright-BDD\n**Languages:** TypeScript, JavaScript, Python, Java, C#\n\nApplies ISTQB test design techniques (EP, BVA) in scenario outlines.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["requirements"],"properties":{"requirements":{"type":"string","minLength":10},"framework":{"type":"string","enum":["cucumber","behave","specflow","cypress-cucumber","playwright-bdd"],"default":"cucumber"},"language":{"type":"string","enum":["javascript","typescript","python","java","csharp"],"default":"typescript"},"includeStepDefs":{"type":"boolean","default":true},"includeDataTables":{"type":"boolean","default":true},"maxScenarios":{"type":"integer","default":15}}}}}},"responses":{"200":{"description":"Generated feature files and step definitions"}}}},"/api/qa/webhooks":{"post":{"tags":["QA CI/CD"],"summary":"CI/CD webhook, trigger test execution from pipelines","description":"Trigger real browser test execution from CI/CD pipelines.\nSupports GitHub Actions, Jenkins, GitLab CI, Azure DevOps.\nAuthenticates via X-GoOmni-Key header.\n\n**Features:**\n- Real Puppeteer browser execution\n- Auto-create defects for failures\n- Callback URL for CI/CD status reporting\n- Branch and commit SHA tracking\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["projectId","organizationId","targetUrl","testCases"],"properties":{"source":{"type":"string","enum":["github","jenkins","gitlab","azure-devops","generic"]},"pipelineId":{"type":"string"},"commitSha":{"type":"string"},"branch":{"type":"string"},"projectId":{"type":"string","format":"uuid"},"organizationId":{"type":"string","format":"uuid"},"targetUrl":{"type":"string","format":"uri"},"environment":{"type":"string","enum":["development","staging","production"]},"testCases":{"type":"array","items":{"type":"object"}},"autoCreateDefects":{"type":"boolean","default":true},"callbackUrl":{"type":"string","format":"uri","description":"URL to POST results back to your CI/CD system"}}}}}},"responses":{"200":{"description":"Execution results with CI/CD metadata"}}}},"/api/voice/calls":{"get":{"tags":["Voice"],"summary":"List voice calls","parameters":[{"name":"kbId","in":"query","schema":{"type":"string"}},{"name":"direction","in":"query","schema":{"type":"string","enum":["inbound","outbound"]}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"List of calls","content":{"application/json":{"schema":{"type":"object","properties":{"calls":{"type":"array","items":{"$ref":"#/components/schemas/VoiceCall"}}}}}}}}}},"/api/voice/phone-numbers":{"get":{"tags":["Voice"],"summary":"List phone numbers","responses":{"200":{"description":"List of phone numbers"}}},"post":{"tags":["Voice"],"summary":"Add phone number","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["phoneNumber","kbId"],"properties":{"phoneNumber":{"type":"string"},"kbId":{"type":"string"}}}}}},"responses":{"201":{"description":"Phone number added"}}}},"/api/voice/outbound/initiate":{"post":{"tags":["Voice Outbound"],"summary":"Initiate outbound call","description":"Start an outbound phone call using the voice agent associated with the\nspecified knowledge base. The agent uses the KB's voice context and tools.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OutboundCallRequest"}}}},"responses":{"200":{"description":"Call initiated","content":{"application/json":{"schema":{"type":"object","properties":{"callId":{"type":"string"},"status":{"type":"string"}}}}}}}}},"/api/voice/tools":{"get":{"tags":["Voice Tools"],"summary":"List all voice tools","responses":{"200":{"description":"List of voice tools"}}},"post":{"tags":["Voice Tools"],"summary":"Create voice tool","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoiceTool"}}}},"responses":{"201":{"description":"Tool created"}}}},"/api/voice/tools/templates":{"get":{"tags":["Voice Tools"],"summary":"List voice tool templates","description":"Returns available tool templates (lead collection, FAQ, HubSpot, etc.)","responses":{"200":{"description":"List of templates"}}}},"/api/voice/tools/{toolId}":{"parameters":[{"name":"toolId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Voice Tools"],"summary":"Get voice tool","responses":{"200":{"description":"Tool details"}}},"patch":{"tags":["Voice Tools"],"summary":"Update voice tool","responses":{"200":{"description":"Tool updated"}}},"delete":{"tags":["Voice Tools"],"summary":"Delete voice tool","responses":{"200":{"description":"Tool deleted"}}}},"/api/voice/tools/{toolId}/assign":{"parameters":[{"name":"toolId","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Voice Tools"],"summary":"Assign tool to knowledge base","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["kbId"],"properties":{"kbId":{"type":"string"}}}}}},"responses":{"200":{"description":"Tool assigned"}}},"delete":{"tags":["Voice Tools"],"summary":"Unassign tool from knowledge base","responses":{"200":{"description":"Tool unassigned"}}}},"/api/livekit/token":{"post":{"tags":["Voice"],"summary":"Get LiveKit session token","description":"Generate a LiveKit access token for browser-based voice chat.","security":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["room","identity"],"properties":{"room":{"type":"string"},"identity":{"type":"string"}}}}}},"responses":{"200":{"description":"LiveKit token","content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string"}}}}}}}}},"/api/rfp/analyze":{"post":{"tags":["RFP"],"summary":"Analyze RFP documents","description":"Extracts requirements, evaluation criteria, and key details from uploaded RFP documents.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RfpAnalysisRequest"}}}},"responses":{"200":{"description":"Analysis results (streamed)"}}}},"/api/rfp/generate":{"post":{"tags":["RFP"],"summary":"Generate proposal sections","description":"Generates proposal content for specified sections using AI and company knowledge bases.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["projectId","sectionIds"],"properties":{"projectId":{"type":"string"},"sectionIds":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Generated sections (streamed)"}}}},"/api/rfp/upload":{"post":{"tags":["RFP"],"summary":"Upload RFP files","requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"projectId":{"type":"string"}}}}}},"responses":{"200":{"description":"File uploaded"}}}},"/api/rfp/sections":{"get":{"tags":["RFP"],"summary":"List RFP sections","parameters":[{"name":"projectId","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"List of sections"}}},"post":{"tags":["RFP"],"summary":"Create RFP section","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RfpSection"}}}},"responses":{"201":{"description":"Section created"}}}},"/api/rfp/generate-document":{"post":{"tags":["RFP"],"summary":"Generate RFP document","description":"Generates a complete proposal document (PDF) from all sections.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["projectId"],"properties":{"projectId":{"type":"string"}}}}}},"responses":{"200":{"description":"Document generated"}}}},"/api/agents/chain":{"post":{"tags":["RFP Agents"],"summary":"Run RFP agent chain","description":"Executes the full RFP agent chain: Analysis → Assessment → Research → Win Themes → Writer → QA.\nEach agent builds on the output of the previous one. Progress is streamed via WebSocket.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AgentChainRequest"}}}},"responses":{"200":{"description":"Chain execution started"}}}},"/api/opportunities/scan":{"post":{"tags":["Opportunities"],"summary":"Start opportunity scan","description":"Starts an asynchronous scan for procurement opportunities across multiple sources:\nSAM.gov, USASpending, Periscope, BidNet, Bonfire, PlanetBids, and more.\nResults are AI-qualified against your search filter criteria.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OpportunityScanRequest"}}}},"responses":{"200":{"description":"Scan started","content":{"application/json":{"schema":{"type":"object","properties":{"scanId":{"type":"string"},"status":{"type":"string"}}}}}}}},"get":{"tags":["Opportunities"],"summary":"List scans","responses":{"200":{"description":"List of scans"}}}},"/api/opportunities/scan/{scanId}":{"parameters":[{"name":"scanId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Opportunities"],"summary":"Get scan status and results","responses":{"200":{"description":"Scan status with opportunities"}}}},"/api/opportunities/list":{"get":{"tags":["Opportunities"],"summary":"List opportunities","parameters":[{"name":"status","in":"query","schema":{"type":"string","enum":["new","qualified","reviewed","applied"]}},{"name":"limit","in":"query","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"List of opportunities","content":{"application/json":{"schema":{"type":"object","properties":{"opportunities":{"type":"array","items":{"$ref":"#/components/schemas/Opportunity"}}}}}}}}}},"/api/search-filters":{"get":{"tags":["Opportunities"],"summary":"List search filters","responses":{"200":{"description":"List of filters"}}},"post":{"tags":["Opportunities"],"summary":"Create search filter","description":"Create a filter defining criteria for opportunity scanning (industries, NAICS codes, set-asides, etc.)","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"industries":{"type":"array","items":{"type":"string"}},"naicsCodes":{"type":"array","items":{"type":"string"}},"states":{"type":"array","items":{"type":"string"}},"setAsides":{"type":"array","items":{"type":"string"}},"keywords":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"Filter created"}}}},"/api/search-filters/taxonomy":{"get":{"tags":["Opportunities"],"summary":"Get taxonomy data","description":"Returns available industries, departments, states, NAICS codes, and set-aside types.","responses":{"200":{"description":"Taxonomy data"}}}},"/api/files/upload":{"post":{"tags":["Files"],"summary":"Upload file","requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"},"projectId":{"type":"string"},"kbId":{"type":"string"}}}}}},"responses":{"200":{"description":"File uploaded"}}}},"/api/files/{fileId}/download":{"parameters":[{"name":"fileId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Files"],"summary":"Download file","responses":{"200":{"description":"File content"}}}},"/api/files/{fileId}/reindex":{"parameters":[{"name":"fileId","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Files"],"summary":"Reindex file","description":"Re-processes and re-indexes a file through the full pipeline.","responses":{"200":{"description":"Reindexing started"}}}},"/api/viewer/convert":{"get":{"tags":["Files"],"summary":"Convert document to HTML","description":"Converts Office documents (DOCX, XLSX) to HTML for viewing.","parameters":[{"name":"url","in":"query","required":true,"schema":{"type":"string"},"description":"S3 URL of the document"}],"responses":{"200":{"description":"Converted HTML"}}}},"/api/search":{"post":{"tags":["Search"],"summary":"Unified search","description":"Search across projects and knowledge bases.","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchRequest"}}}},"responses":{"200":{"description":"Search results"}}}},"/api/search/enhanced":{"post":{"tags":["Search"],"summary":"Enhanced search with filters","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string"},"filters":{"type":"object"},"kbIds":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Enhanced search results"}}}},"/api/campaigns":{"get":{"tags":["Campaigns"],"summary":"List campaigns","responses":{"200":{"description":"List of campaigns"}}},"post":{"tags":["Campaigns"],"summary":"Create campaign","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["name","kbId"],"properties":{"name":{"type":"string"},"kbId":{"type":"string","description":"Knowledge base whose voice agent will handle calls"}}}}}},"responses":{"201":{"description":"Campaign created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Campaign"}}}}}}},"/api/campaigns/{campaignId}":{"parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Campaigns"],"summary":"Get campaign","responses":{"200":{"description":"Campaign details"}}},"patch":{"tags":["Campaigns"],"summary":"Update campaign","responses":{"200":{"description":"Campaign updated"}}},"delete":{"tags":["Campaigns"],"summary":"Delete campaign","responses":{"200":{"description":"Campaign deleted"}}}},"/api/campaigns/{campaignId}/contacts":{"parameters":[{"name":"campaignId","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Campaigns"],"summary":"Add contacts to campaign","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["contacts"],"properties":{"contacts":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"phoneNumber":{"type":"string"},"metadata":{"type":"object"}}}}}}}}},"responses":{"200":{"description":"Contacts added"}}}},"/api/sms/send":{"post":{"tags":["SMS"],"summary":"Send SMS","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["to","body"],"properties":{"to":{"type":"string","description":"Phone number (E.164)"},"body":{"type":"string","description":"Message body"},"from":{"type":"string","description":"From number (optional, uses org default)"}}}}}},"responses":{"200":{"description":"SMS sent"}}}},"/api/sms/history":{"get":{"tags":["SMS"],"summary":"Get SMS history","responses":{"200":{"description":"SMS history"}}}},"/api/integrations":{"get":{"tags":["Integrations"],"summary":"List integrations","responses":{"200":{"description":"List of integrations"}}},"post":{"tags":["Integrations"],"summary":"Create integration","responses":{"201":{"description":"Integration created"}}}},"/api/integrations/twilio":{"get":{"tags":["Integrations"],"summary":"Get Twilio integration","responses":{"200":{"description":"Twilio config"}}},"post":{"tags":["Integrations"],"summary":"Configure Twilio integration","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["accountSid","authToken"],"properties":{"accountSid":{"type":"string"},"authToken":{"type":"string"}}}}}},"responses":{"200":{"description":"Twilio configured"}}}},"/api/integrations/hubspot":{"get":{"tags":["Integrations"],"summary":"Get HubSpot integration","responses":{"200":{"description":"HubSpot config"}}},"post":{"tags":["Integrations"],"summary":"Configure HubSpot integration","responses":{"200":{"description":"HubSpot configured"}}}},"/api/integrations/test-connection":{"post":{"tags":["PM Integrations"],"summary":"Test connection to a PM tool (Jira, Asana, Linear, Azure DevOps)","description":"Verifies that the stored credentials for an integration are valid.\nUses the official SDK for each platform to test connectivity.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId"],"properties":{"integrationId":{"type":"string","format":"uuid","description":"ID of the integration to test"}}}}}},"responses":{"200":{"description":"Connection test result","content":{"application/json":{"schema":{"type":"object","properties":{"platform":{"type":"string","enum":["jira","asana","linear","azure_devops"]},"success":{"type":"boolean"},"projectName":{"type":"string","description":"Name of the connected project/workspace (varies by platform)"},"error":{"type":"string"}}}}}}}}},"/api/integrations/push":{"post":{"tags":["PM Integrations"],"summary":"Push stories, test cases, or defects to Jira / Asana / Linear / Azure DevOps","description":"Unified endpoint to push any item type (story, testCase, defect) to any connected PM tool.\nReads the integration config to determine credentials and routes to the correct SDK.\n\n**Supported platforms & SDKs:**\n- **Jira**, `jira.js` (Stories, Bugs, Tasks with issue linking)\n- **Asana**, `asana` (Tasks, subtasks under projects)\n- **Linear**, `@linear/sdk` (Issues, sub-issues with priority mapping)\n- **Azure DevOps**, `azure-devops-node-api` (User Stories, Bugs, Test Cases with XML steps)\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId","itemType","items"],"properties":{"integrationId":{"type":"string","format":"uuid","description":"Integration ID (must be jira, asana, linear, or azure_devops type)"},"itemType":{"type":"string","enum":["story","testCase","defect"],"description":"What kind of item to push"},"items":{"type":"array","description":"Array of items to push (structure depends on itemType)","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"userStory":{"type":"string"},"acceptanceCriteria":{"type":"array","items":{"type":"object","properties":{"given":{"type":"string"},"when":{"type":"string"},"then":{"type":"string"}}}},"priority":{"type":"string","enum":["critical","high","medium","low"]},"storyPoints":{"type":"number"},"labels":{"type":"array","items":{"type":"string"}},"id":{"type":"string","description":"Test case ID (for testCase items)"},"steps":{"type":"array","description":"Test case steps (for testCase items)","items":{"type":"object","properties":{"stepNumber":{"type":"integer"},"action":{"type":"string"},"expectedResult":{"type":"string"}}}},"severity":{"type":"string","description":"Defect severity"},"stepsToReproduce":{"type":"string","description":"Defect reproduction steps"},"environment":{"type":"string"},"pageUrl":{"type":"string"},"linkedIssueKey":{"type":"string","description":"Jira issue key to link (for Jira defects/tests)"},"parentIssueId":{"type":"string","description":"Linear parent issue ID (for Linear sub-issues)"},"parentTaskGid":{"type":"string","description":"Asana parent task GID (for Asana subtasks)"},"parentWorkItemId":{"type":"integer","description":"Azure DevOps parent work item ID"}}}}}}}}},"responses":{"200":{"description":"Push results","content":{"application/json":{"schema":{"type":"object","properties":{"platform":{"type":"string","enum":["jira","asana","linear","azure_devops"]},"results":{"type":"array","items":{"type":"object","properties":{"success":{"type":"boolean"},"issueKey":{"type":"string","description":"Jira issue key (e.g., PROJ-123)"},"issueUrl":{"type":"string","description":"Direct URL to the created item"},"taskGid":{"type":"string","description":"Asana task GID"},"issueIdentifier":{"type":"string","description":"Linear issue identifier (e.g., ENG-42)"},"workItemId":{"type":"integer","description":"Azure DevOps work item ID"},"error":{"type":"string"}}}}}}}}}}}},"/api/google-drive/auth":{"get":{"tags":["Google Drive"],"summary":"Start Google Drive OAuth","description":"Redirects to Google OAuth consent screen.","responses":{"302":{"description":"Redirect to Google OAuth"}}},"post":{"tags":["Google Drive"],"summary":"Exchange OAuth code","responses":{"200":{"description":"Auth token stored"}}}},"/api/google-drive/folders":{"get":{"tags":["Google Drive"],"summary":"List Drive folders","parameters":[{"name":"parentId","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"List of folders"}}}},"/api/google-drive/files":{"get":{"tags":["Google Drive"],"summary":"List Drive files","parameters":[{"name":"folderId","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"List of files"}}}},"/api/google-drive/import":{"post":{"tags":["Google Drive"],"summary":"Import file from Drive","description":"Downloads a single file from Google Drive and processes it into a knowledge base.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["fileId","kbId"],"properties":{"fileId":{"type":"string"},"kbId":{"type":"string"}}}}}},"responses":{"200":{"description":"Import started"}}}},"/api/google-drive/bulk-import":{"post":{"tags":["Google Drive"],"summary":"Bulk import from Drive","description":"Imports all files from linked Google Drive folders into a knowledge base.\nQueues each file for async processing through the indexing pipeline.\n","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["kbId"],"properties":{"kbId":{"type":"string"},"folderId":{"type":"string"}}}}}},"responses":{"200":{"description":"Bulk import started"}}}},"/api/google-drive/index":{"post":{"tags":["Google Drive"],"summary":"Index Drive content","description":"Triggers indexing of Google Drive content for a knowledge base.","responses":{"200":{"description":"Indexing started"}}}},"/api/agent-runs":{"get":{"tags":["Agent Runs"],"summary":"List agent runs","parameters":[{"name":"projectId","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer","default":20}}],"responses":{"200":{"description":"List of agent runs"}}}},"/api/agent-runs/{runId}":{"parameters":[{"name":"runId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Agent Runs"],"summary":"Get agent run details","description":"Returns execution details, inputs, outputs, and logs for an agent run.","responses":{"200":{"description":"Agent run details"}}}},"/api/knowledge-bases/{id}/crawl":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Website Crawling"],"summary":"Crawl and index a website","description":"Starts a full website crawl for a website-type knowledge base.\nThe crawler follows links up to the configured depth, extracts content\nfrom each page, runs Lighthouse analysis, and indexes everything.\n\nPipeline: Crawl → Extract → Lighthouse → Chunk → Embed → Index\n","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"maxDepth":{"type":"integer","default":3,"description":"Maximum link depth to follow"},"maxPages":{"type":"integer","default":100,"description":"Maximum pages to crawl"}}}}}},"responses":{"200":{"description":"Crawl started"}}}},"/api/knowledge-bases/{id}/reset-indexing":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Website Crawling"],"summary":"Reset all indexing","description":"Completely resets a knowledge base's indexing. Deletes all files,\nclears S3 content, purges SQS queues, and resets counters.\nUse this for a clean re-crawl/re-index.\n","responses":{"200":{"description":"Indexing reset"}}}},"/api/knowledge-bases/{id}/pipeline-health":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Website Crawling"],"summary":"Check pipeline health","description":"Checks the health of the indexing pipeline for a knowledge base.\nReports stuck files, failed jobs, and queue status.\nOptionally auto-fixes stuck files.\n","parameters":[{"name":"autoFix","in":"query","schema":{"type":"boolean","default":false},"description":"Automatically retry stuck files"}],"responses":{"200":{"description":"Pipeline health status","content":{"application/json":{"schema":{"type":"object","properties":{"healthy":{"type":"boolean"},"totalFiles":{"type":"integer"},"indexedFiles":{"type":"integer"},"processingFiles":{"type":"integer"},"errorFiles":{"type":"integer"},"stuckFiles":{"type":"integer"}}}}}}}}},"/api/knowledge-bases/{id}/analysis":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Site Analysis"],"summary":"Get KB-level site analysis","description":"Returns aggregated analysis across all pages in a website knowledge base:\n- Average Lighthouse scores (performance, accessibility, SEO, best practices)\n- Page classification breakdown (by content type, design quality)\n- Navigation structure overview\n- Responsive design scores\n","responses":{"200":{"description":"Site analysis data","content":{"application/json":{"schema":{"type":"object","properties":{"lighthouseAverages":{"type":"object","properties":{"performance":{"type":"number"},"accessibility":{"type":"number"},"seo":{"type":"number"},"bestPractices":{"type":"number"}}},"pageCount":{"type":"integer"},"navigation":{"type":"object"}}}}}}}}},"/api/knowledge-bases/{id}/files-analysis":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Site Analysis"],"summary":"Get per-page analysis","description":"Returns detailed analysis for every page in the knowledge base:\n- Lighthouse scores per page\n- Vision AI classification (page type, content intent)\n- Navigation structures per page\n- Content type mapping\n\nUse `includeDetails=true` for full S3 data including element-level details.\n","parameters":[{"name":"includeDetails","in":"query","schema":{"type":"boolean","default":false},"description":"Include full Vision AI and navigation details from S3"}],"responses":{"200":{"description":"Per-page analysis data"}}}},"/api/knowledge-bases/{id}/files/{fileId}/analysis":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fileId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Site Analysis"],"summary":"Get single page analysis","description":"Full Vision AI + Lighthouse analysis for one page.","responses":{"200":{"description":"Page analysis data"}}}},"/api/knowledge-bases/{id}/lighthouse-details/{fileId}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"fileId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Site Analysis"],"summary":"Get full Lighthouse report","description":"Returns the complete Lighthouse report for a page including:\n- **Performance**: LCP, FID, CLS, TTFB, speed index\n- **Accessibility**: Color contrast, ARIA, alt text, keyboard nav, WCAG compliance\n- **SEO**: Meta descriptions, titles, crawlability, structured data, canonical URLs\n- **Best Practices**: HTTPS, console errors, image optimization\n\nEach category includes specific audit items with pass/fail status and recommendations.\n","responses":{"200":{"description":"Full Lighthouse report","content":{"application/json":{"schema":{"type":"object","properties":{"performance":{"type":"object","properties":{"score":{"type":"number"},"insights":{"type":"array","items":{"type":"object"}}}},"accessibility":{"type":"object","properties":{"score":{"type":"number"},"insights":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"description":{"type":"string"},"score":{"type":"number"}}}}}},"seo":{"type":"object"},"bestPractices":{"type":"object"}}}}}}}}},"/api/knowledge-bases/{id}/content-type-analysis":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Content Type Analysis"],"summary":"Get content type analysis results","description":"Returns the AI-generated content type analysis from S3.","responses":{"200":{"description":"Content type analysis"}}}},"/api/knowledge-bases/{id}/master-context/regenerate":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Master Context"],"summary":"Regenerate KB master context","description":"Uses AI to regenerate the master context document from all indexed content.\nThe master context is a comprehensive summary used by agents and voice bots.\nOptionally provide a custom prompt to guide generation.\n","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"customPrompt":{"type":"string","description":"Optional custom prompt to guide context generation"}}}}}},"responses":{"200":{"description":"Master context regenerated"}}}},"/api/knowledge-bases/{id}/master-context/save":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Master Context"],"summary":"Save master context","description":"Manually save or edit the master context.","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string"}}}}}},"responses":{"200":{"description":"Master context saved"}}}},"/api/knowledge-bases/{id}/voice-context/regenerate":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Voice Context"],"summary":"Regenerate voice context","description":"AI-generates voice agent instructions and FAQs from the knowledge base content.\nThis context is used by the voice agent during phone calls.\n","responses":{"200":{"description":"Voice context regenerated"}}}},"/api/knowledge-bases/{id}/voice-context/save":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Voice Context"],"summary":"Save voice context","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"instructions":{"type":"string"},"faqs":{"type":"array","items":{"type":"object","properties":{"question":{"type":"string"},"answer":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"Voice context saved"}}}},"/api/knowledge-bases/{id}/ontology":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"get":{"tags":["Ontology"],"summary":"Get KB ontology","description":"Returns extracted entities, relationships, and type breakdowns from\nall indexed documents. Entities include people, organizations, concepts,\ndates, and domain-specific terms.\n","responses":{"200":{"description":"Ontology data","content":{"application/json":{"schema":{"type":"object","properties":{"entities":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"type":{"type":"string"},"frequency":{"type":"integer"}}}},"relationships":{"type":"array","items":{"type":"object"}},"typeBreakdown":{"type":"object"}}}}}}}}},"/api/knowledge-bases/{id}/optimize":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"post":{"tags":["Ontology"],"summary":"Optimize KB with domain ontology","description":"Re-runs ontology tagging with a specific domain or custom ontology.\nImproves entity extraction and search relevance for domain-specific content.\n","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"domain":{"type":"string","description":"Domain for targeted ontology (e.g., \"healthcare\", \"legal\")"},"customOntology":{"type":"object","description":"Custom ontology definition"}}}}}},"responses":{"200":{"description":"Optimization started"}}}},"/api/validation/pii-detect":{"post":{"tags":["Validation"],"summary":"Detect PII in content","description":"Scans content for Personally Identifiable Information:\n- Social Security Numbers (SSN)\n- Credit card numbers\n- Email addresses\n- Phone numbers\n\nOptionally redacts detected PII by replacing with masked values.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string","description":"Text content to scan"},"redact":{"type":"boolean","default":false,"description":"Replace detected PII with masked values"},"piiTypes":{"type":"array","items":{"type":"string","enum":["ssn","credit_card","email","phone"]},"description":"Specific PII types to detect (defaults to all)"}}}}}},"responses":{"200":{"description":"PII detection results","content":{"application/json":{"schema":{"type":"object","properties":{"hasPII":{"type":"boolean"},"piiItems":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"},"position":{"type":"integer"},"redactedValue":{"type":"string"}}}},"redactedContent":{"type":"string","description":"Content with PII replaced (only if redact=true)"},"summary":{"type":"string"}}}}}}}}},"/api/validation/compliance-check":{"post":{"tags":["Validation"],"summary":"Check content compliance","description":"Validates content against policy rules and compliance requirements.\nChecks for regulatory compliance, policy adherence, and content standards.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string"},"rules":{"type":"array","items":{"type":"string"},"description":"Compliance rules to check against"},"policyDocument":{"type":"string","description":"Reference policy document"}}}}}},"responses":{"200":{"description":"Compliance check results"}}}},"/api/validation/quality-score":{"post":{"tags":["Validation"],"summary":"Score content quality","description":"Evaluates content quality across multiple dimensions:\ncompleteness, accuracy, clarity, and professional tone.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string"},"criteria":{"type":"array","items":{"type":"string"},"description":"Quality criteria to evaluate"}}}}}},"responses":{"200":{"description":"Quality scores"}}}},"/api/validation/citation-validate":{"post":{"tags":["Validation"],"summary":"Validate citations","description":"Validates that citations in content are accurate and traceable\nto source documents in the knowledge base.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content","kbId"],"properties":{"content":{"type":"string"},"kbId":{"type":"string","description":"Knowledge base to validate citations against"}}}}}},"responses":{"200":{"description":"Citation validation results"}}}},"/api/document/export-pdf":{"post":{"tags":["Files"],"summary":"Export content to PDF","description":"Generates a PDF from provided content (migration reports, proposals, etc.)","requestBody":{"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string"},"title":{"type":"string"},"template":{"type":"string","enum":["migration-report","proposal","generic"]}}}}}},"responses":{"200":{"description":"PDF file"}}}},"/api/documents/accessibility/audit":{"post":{"tags":["Document Accessibility"],"summary":"WCAG 2.1 / Section 508 accessibility audit","description":"Analyze a PDF or document for ADA compliance. Checks tagged structure,\nreading order, alt text, headings, bookmarks, form labels, color contrast,\nand more. Returns a detailed audit with compliance score and remediation plan.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"URL to a publicly accessible document"},"content":{"type":"string","description":"Raw text or HTML content to analyze"},"fileId":{"type":"string","description":"Reference to an already-uploaded file in a knowledge base"},"knowledgeBaseId":{"type":"string","description":"Knowledge base ID (required if using fileId)"},"standard":{"type":"string","enum":["wcag-2.1-aa","wcag-2.1-aaa","section-508"],"default":"wcag-2.1-aa","description":"Accessibility standard to audit against"},"includeRemediation":{"type":"boolean","default":true,"description":"Include a prioritized remediation plan for failures"}}}}}},"responses":{"200":{"description":"Accessibility audit report","content":{"application/json":{"schema":{"type":"object","properties":{"audit":{"type":"object","properties":{"findings":{"type":"array","items":{"type":"object","properties":{"ruleId":{"type":"string"},"status":{"type":"string","enum":["pass","fail","warning","not-applicable"]},"severity":{"type":"string","enum":["critical","major","minor"]},"description":{"type":"string"},"location":{"type":"string"},"remediation":{"type":"string"}}}},"summary":{"type":"object","properties":{"totalRules":{"type":"integer"},"passed":{"type":"integer"},"failed":{"type":"integer"},"warnings":{"type":"integer"},"complianceScore":{"type":"integer"},"overallStatus":{"type":"string","enum":["compliant","partially-compliant","non-compliant"]}}},"documentProfile":{"type":"object","properties":{"estimatedPageCount":{"type":"integer"},"hasImages":{"type":"boolean"},"hasTables":{"type":"boolean"},"primaryLanguage":{"type":"string"},"readingLevel":{"type":"string"},"isTaggedPdf":{"type":"boolean"}}}}},"remediationPlan":{"type":"object","nullable":true,"properties":{"estimatedEffort":{"type":"string"},"steps":{"type":"array","items":{"type":"object","properties":{"order":{"type":"integer"},"ruleId":{"type":"string"},"severity":{"type":"string"},"action":{"type":"string"}}}}}}}}}}}}}},"/api/documents/accessibility/remediate":{"post":{"tags":["Document Accessibility"],"summary":"Remediate a PDF for ADA/WCAG compliance","description":"Upload a PDF and receive a remediated, accessibility-compliant version.\nThe endpoint extracts text with layout data, uses AI to classify content\nstructure (headings, paragraphs, lists, images), then modifies the PDF\nbinary to add proper tags, metadata, language, bookmarks, and tab order.\nReturns the fixed PDF as a downloadable file or base64 JSON.\n","requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"PDF file to remediate"},"title":{"type":"string","description":"Override document title (otherwise AI-inferred)"},"language":{"type":"string","description":"ISO 639-1 language code (default auto-detected)"},"author":{"type":"string","description":"Document author"}}}},"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"URL to a publicly accessible PDF"},"base64":{"type":"string","description":"Base64-encoded PDF content"},"title":{"type":"string"},"language":{"type":"string"},"author":{"type":"string"}}}}}},"parameters":[{"name":"format","in":"query","schema":{"type":"string","enum":["json"]},"description":"Set to \"json\" to receive base64 PDF + metadata; omit for a binary download"}],"responses":{"200":{"description":"Remediated PDF","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"object","properties":{"remediatedPdf":{"type":"string","description":"Base64-encoded remediated PDF"},"fileName":{"type":"string"},"changes":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string","enum":["metadata","bookmark","structure","alt-text","reading-order"]},"description":{"type":"string"},"page":{"type":"integer"}}}},"summary":{"type":"object","properties":{"totalChanges":{"type":"integer"},"metadataFixed":{"type":"integer"},"bookmarksAdded":{"type":"integer"},"structureTagsAdded":{"type":"integer"},"altTextsAdded":{"type":"integer"}}}}}}}}}}},"/api/documents/analytics":{"post":{"tags":["Document Analytics"],"summary":"Analyze document structure, readability, and quality","description":"Multi-analysis endpoint for document content. Computes Flesch reading ease,\nFlesch-Kincaid grade level, structure breakdown (headings, lists, tables),\nmetadata extraction, language detection, quality scoring, and AI summary.\nSelect which analyses to run via the `analyses` array.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string","description":"Document text content to analyze"},"url":{"type":"string","description":"Source URL (for metadata only)"},"fileName":{"type":"string","description":"Original file name (for metadata only)"},"analyses":{"type":"array","items":{"type":"string","enum":["structure","readability","metadata","language","quality","summary"]},"default":["structure","readability","metadata","language"],"description":"Which analyses to run"}}}}}},"responses":{"200":{"description":"Analysis results","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"object","properties":{"structure":{"type":"object","properties":{"lineCount":{"type":"integer"},"paragraphCount":{"type":"integer"},"headingCount":{"type":"integer"},"headings":{"type":"array","items":{"type":"string"}},"estimatedPageCount":{"type":"integer"}}},"readability":{"type":"object","properties":{"fleschReadingEase":{"type":"number"},"fleschKincaidGrade":{"type":"number"},"gradeLabel":{"type":"string"},"adaCompliance":{"type":"string"},"estimatedReadingTimeMinutes":{"type":"integer"}}},"language":{"type":"object","properties":{"primary":{"type":"string"},"confidence":{"type":"number"}}},"quality":{"type":"object","properties":{"score":{"type":"integer"},"strengths":{"type":"array","items":{"type":"string"}},"weaknesses":{"type":"array","items":{"type":"string"}}}},"summary":{"type":"object","properties":{"oneLiner":{"type":"string"},"keyPoints":{"type":"array","items":{"type":"string"}},"topics":{"type":"array","items":{"type":"string"}}}}}}}}}}}}}},"/api/documents/pii/scan":{"post":{"tags":["Document PII"],"summary":"Scan for personally identifiable information","description":"Detect PII in document content: SSNs, credit cards, emails, phone numbers,\naddresses, dates of birth, driver's licenses, passport numbers, IP addresses,\nbank accounts, and medical record numbers. Optionally redact detected PII.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string","description":"Document text content to scan"},"redact":{"type":"boolean","default":false,"description":"If true, returns redacted content with PII masked"},"categories":{"type":"array","items":{"type":"string","enum":["ssn","credit-card","email","phone","address","date-of-birth","drivers-license","passport","ip-address","bank-account","medical-record"]},"description":"Limit scan to specific PII categories (default is all)"}}}}}},"responses":{"200":{"description":"PII scan results","content":{"application/json":{"schema":{"type":"object","properties":{"findings":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"name":{"type":"string"},"category":{"type":"string"},"sensitivity":{"type":"string","enum":["critical","high","medium","low"]},"count":{"type":"integer"}}}},"summary":{"type":"object","properties":{"totalPiiInstances":{"type":"integer"},"uniqueTypes":{"type":"integer"},"riskLevel":{"type":"string","enum":["none","low","medium","high","critical"]},"criticalFindings":{"type":"integer"}}},"redactedContent":{"type":"string","description":"Only present if redact=true"}}}}}}}}},"/api/tickets/sync":{"post":{"tags":["Ticket Sync"],"summary":"Pull and normalize tickets from Jira/Asana","description":"Sync all tickets from an external PM integration. Returns normalized tickets\nacross platforms and text chunks ready for KB indexing.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId"],"properties":{"integrationId":{"type":"string","format":"uuid","description":"PM integration ID (Jira, Asana)"}}}}}},"responses":{"200":{"description":"Sync results with normalized tickets","content":{"application/json":{"schema":{"type":"object","properties":{"syncResult":{"$ref":"#/components/schemas/TicketSyncResult"},"tickets":{"type":"array","items":{"$ref":"#/components/schemas/NormalizedTicket"}},"chunks":{"type":"array","items":{"type":"object","properties":{"content":{"type":"string"},"metadata":{"type":"object"}}}},"ticketCount":{"type":"integer"}}}}}}}}},"/api/tickets/analyze":{"post":{"tags":["Ticket Analysis"],"summary":"AI-powered ticket quality analysis","description":"Analyze ticket quality for specific tickets or all tickets in an integration.\nReturns quality scores (1-10), issues, suggestions, and missing fields.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId"],"properties":{"integrationId":{"type":"string","format":"uuid"},"ticketIds":{"type":"array","items":{"type":"string"},"description":"Specific ticket IDs to analyze (defaults to all)"}}}}}},"responses":{"200":{"description":"Quality analysis results","content":{"application/json":{"schema":{"type":"object","properties":{"analyses":{"type":"array","items":{"type":"object","properties":{"ticket":{"$ref":"#/components/schemas/NormalizedTicket"},"qualityScore":{"type":"integer","minimum":1,"maximum":10},"issues":{"type":"array","items":{"type":"string"}},"suggestions":{"type":"array","items":{"type":"string"}},"missingFields":{"type":"array","items":{"type":"string"}}}}},"totalTickets":{"type":"integer"},"analyzedCount":{"type":"integer"}}}}}}}}},"/api/tickets/generate":{"post":{"tags":["Ticket Generation"],"summary":"Generate structured agile tickets from raw input","description":"Create well-structured agile tickets from raw input (email, bug report,\nfeature request, support message). Uses the existing ticket landscape to\navoid duplicates and reference related work. Supports multi-channel input.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId","input"],"properties":{"integrationId":{"type":"string","format":"uuid"},"input":{"type":"string","minLength":10,"description":"Raw input text (email body, bug report, feature request)"},"channel":{"type":"string","enum":["email","support","webhook","manual","slack"],"default":"manual"},"pushToIntegration":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"Generated tickets","content":{"application/json":{"schema":{"type":"object","properties":{"generated":{"type":"array","items":{"$ref":"#/components/schemas/GeneratedTicket"}},"generatedCount":{"type":"integer"},"existingTicketCount":{"type":"integer"},"channel":{"type":"string"}}}}}}}}},"/api/tickets/enhance":{"post":{"tags":["Ticket Enhancement"],"summary":"Enhance tickets with agile best practices","description":"Apply Scrum, Kanban, or hybrid agile best practices to existing tickets.\nReturns improved titles, structured descriptions, Given/When/Then acceptance\ncriteria, Fibonacci story points, and proper categorization.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId","ticketIds"],"properties":{"integrationId":{"type":"string","format":"uuid"},"ticketIds":{"type":"array","items":{"type":"string"},"minItems":1},"methodology":{"type":"string","enum":["scrum","kanban","hybrid"],"default":"scrum"},"pushUpdates":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"Enhanced tickets with change summaries","content":{"application/json":{"schema":{"type":"object","properties":{"enhanced":{"type":"array","items":{"type":"object","properties":{"externalId":{"type":"string"},"enhanced":{"$ref":"#/components/schemas/GeneratedTicket"},"changes":{"type":"array","items":{"type":"string"}}}}},"enhancedCount":{"type":"integer"},"methodology":{"type":"string"}}}}}}}}},"/api/tickets/duplicates":{"post":{"tags":["Ticket Deduplication"],"summary":"Find semantically similar or overlapping tickets","description":"Uses AI to identify duplicate or overlapping tickets by semantic similarity,\nincluding cases where the titles differ. Returns confidence scores and explanations.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId"],"properties":{"integrationId":{"type":"string","format":"uuid"}}}}}},"responses":{"200":{"description":"Duplicate detection results","content":{"application/json":{"schema":{"type":"object","properties":{"duplicates":{"type":"array","items":{"type":"object","properties":{"sourceTicket":{"$ref":"#/components/schemas/NormalizedTicket"},"matchedTicket":{"$ref":"#/components/schemas/NormalizedTicket"},"similarityScore":{"type":"number","minimum":0,"maximum":1},"reason":{"type":"string"}}}},"duplicateCount":{"type":"integer"},"totalTickets":{"type":"integer"}}}}}}}}},"/api/tickets/status":{"post":{"tags":["Ticket Status"],"summary":"Intelligent ticket status lookup","description":"\"Has this bug been fixed?\" Search the ticket landscape with natural language.\nReturns matching tickets, current status, and a recommendation (already_resolved,\nin_progress, create_new, consolidate, or reopen).\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId","query"],"properties":{"integrationId":{"type":"string","format":"uuid"},"query":{"type":"string","minLength":3,"description":"Natural language query (e.g. \"Has the Safari freeze been fixed?\")"}}}}}},"responses":{"200":{"description":"Status lookup results with recommendations","content":{"application/json":{"schema":{"type":"object","properties":{"matchedTickets":{"type":"array","items":{"type":"object","properties":{"externalId":{"type":"string"},"title":{"type":"string"},"status":{"type":"string"},"relevance":{"type":"string","enum":["exact_match","related","partial"]},"url":{"type":"string"},"platform":{"type":"string"}}}},"recommendation":{"type":"string","enum":["already_resolved","in_progress","create_new","consolidate","reopen"]},"explanation":{"type":"string"},"suggestedAction":{"type":"string"},"totalTicketsSearched":{"type":"integer"}}}}}}}}},"/api/tickets/consolidate":{"post":{"tags":["Ticket Consolidation"],"summary":"Merge cross-channel duplicate tickets","description":"Identify and merge duplicate tickets from multiple channels into canonical\nentries. Groups related tickets, generates consolidated tickets, and\nrecommends which to keep vs close.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId"],"properties":{"integrationId":{"type":"string","format":"uuid"},"newInput":{"type":"string","description":"Optional new input to check against existing tickets"},"newChannel":{"type":"string","description":"Channel of the new input"},"threshold":{"type":"number","minimum":0,"maximum":1,"default":0.7,"description":"Similarity threshold for grouping (0.0-1.0)"}}}}}},"responses":{"200":{"description":"Consolidation results","content":{"application/json":{"schema":{"type":"object","properties":{"duplicateGroups":{"type":"array","items":{"type":"object","properties":{"ticketIds":{"type":"array","items":{"type":"string"}},"tickets":{"type":"array","items":{"$ref":"#/components/schemas/NormalizedTicket"}}}}},"consolidatedTickets":{"type":"array","items":{"type":"object"}},"totalDuplicatePairs":{"type":"integer"},"totalGroups":{"type":"integer"}}}}}}}}},"/api/tickets/inbound":{"post":{"tags":["Ticket Inbound"],"summary":"Universal multi-channel ticket intake","description":"Process incoming requests from any channel (email, support form, Slack, webhook).\nParses raw input, checks for duplicates against existing tickets, generates\nstructured agile tickets, and returns a recommendation (create, consolidate, skip).\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId","channel","rawContent"],"properties":{"integrationId":{"type":"string","format":"uuid"},"channel":{"type":"string","enum":["email","support_form","webhook","slack","intercom","other"]},"rawContent":{"type":"string","minLength":5},"metadata":{"type":"object","properties":{"senderEmail":{"type":"string","format":"email"},"senderName":{"type":"string"},"subject":{"type":"string"},"urgency":{"type":"string"},"attachments":{"type":"array","items":{"type":"string"}},"sourceUrl":{"type":"string","format":"uri"},"customFields":{"type":"object","additionalProperties":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"Inbound processing results","content":{"application/json":{"schema":{"type":"object","properties":{"channel":{"type":"string"},"recommendation":{"type":"string","enum":["create","consolidate","skip"]},"generatedTickets":{"type":"array","items":{"$ref":"#/components/schemas/GeneratedTicket"}},"relatedExistingTickets":{"type":"array","items":{"type":"object"}},"existingTicketCount":{"type":"integer"},"processedAt":{"type":"string","format":"date-time"}}}}}}}}},"/api/tickets/inbound/webhook":{"post":{"tags":["Ticket Inbound"],"summary":"Public webhook for external systems","description":"Machine-to-machine webhook endpoint for email services (SendGrid, Mailgun),\nsupport platforms (Intercom, Zendesk), or custom integrations.\nAuthenticated via API key (X-API-Key header or Authorization: Bearer).\n","security":[{"apiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["organizationId","integrationId","channel","content"],"properties":{"organizationId":{"type":"string","format":"uuid"},"integrationId":{"type":"string","format":"uuid"},"channel":{"type":"string","enum":["email","support_form","webhook","slack","intercom"]},"content":{"type":"string","minLength":5},"subject":{"type":"string"},"senderEmail":{"type":"string","format":"email"},"senderName":{"type":"string"},"urgency":{"type":"string","enum":["low","medium","high","critical"]},"customFields":{"type":"object","additionalProperties":{"type":"string"}}}}}}},"responses":{"200":{"description":"Webhook processing confirmation","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean"},"channel":{"type":"string"},"generatedTickets":{"type":"array","items":{"$ref":"#/components/schemas/GeneratedTicket"}},"generatedCount":{"type":"integer"},"processedAt":{"type":"string","format":"date-time"}}}}}}}}},"/api/tickets/dev/list":{"get":{"tags":["Dev Workflow"],"summary":"Browse available tickets with filters","description":"List tickets from a PM integration, filtered by status, priority, type, or\nassignee. Sorted by priority (critical first). Designed for Cursor/CoPilot.\n","parameters":[{"name":"integrationId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"status","in":"query","schema":{"type":"string","enum":["open","in_progress","done","blocked"]}},{"name":"priority","in":"query","schema":{"type":"string","enum":["critical","high","medium","low"]}},{"name":"type","in":"query","schema":{"type":"string","enum":["feature","bug","task","spike"]}},{"name":"assignee","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Filtered ticket list","content":{"application/json":{"schema":{"type":"object","properties":{"tickets":{"type":"array","items":{"$ref":"#/components/schemas/NormalizedTicket"}},"total":{"type":"integer"},"platform":{"type":"string"},"filters":{"type":"object"}}}}}}}}},"/api/tickets/dev/claim":{"post":{"tags":["Dev Workflow"],"summary":"Claim ticket and get AI execution plan","description":"Developer claims a ticket for implementation. Returns full ticket context,\nAI-generated step-by-step execution plan, related tickets, blockers,\nsuggested approach, and complexity estimate. Designed for Cursor/CoPilot.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId","ticketId"],"properties":{"integrationId":{"type":"string","format":"uuid"},"ticketId":{"type":"string"}}}}}},"responses":{"200":{"description":"Claim context with execution plan","content":{"application/json":{"schema":{"type":"object","properties":{"ticket":{"$ref":"#/components/schemas/NormalizedTicket"},"executionPlan":{"type":"string"},"contextSummary":{"type":"string"},"relatedTickets":{"type":"array","items":{"$ref":"#/components/schemas/NormalizedTicket"}},"blockers":{"type":"array","items":{"type":"string"}},"suggestedApproach":{"type":"string"},"estimatedComplexity":{"type":"string","enum":["low","medium","high"]},"claimedBy":{"type":"string"},"claimedAt":{"type":"string","format":"date-time"}}}}}}}}},"/api/tickets/dev/complete":{"post":{"tags":["Dev Workflow"],"summary":"Mark ticket done and update PM tool","description":"Developer marks a ticket complete after implementation. Automatically updates\nthe ticket in Jira/Asana with status change, work summary, files changed,\ntest results, commit hash, and PR URL.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["integrationId","ticketId","status","workSummary"],"properties":{"integrationId":{"type":"string","format":"uuid"},"ticketId":{"type":"string"},"status":{"type":"string","enum":["done","in_review"]},"workSummary":{"type":"string","minLength":10},"filesChanged":{"type":"array","items":{"type":"string"}},"testResults":{"type":"string"},"commitHash":{"type":"string"},"prUrl":{"type":"string","format":"uri"}}}}}},"responses":{"200":{"description":"Completion confirmation","content":{"application/json":{"schema":{"type":"object","properties":{"ticketId":{"type":"string"},"status":{"type":"string"},"platform":{"type":"string"},"updated":{"type":"boolean"},"updateError":{"type":"string"},"completedBy":{"type":"string"},"completedAt":{"type":"string","format":"date-time"}}}}}}}}},"/api/collect":{"post":{"operationId":"analyticsCollect","summary":"Ingest pageviews, custom events, and identify payloads","description":"Primary tracker endpoint. Accepts Umami-style `{type, payload}` bodies.\nDerives `sessionId` and `visitId` server-side from IP, user agent, and\nwebsite salt. CORS open for browser beacons.\n","tags":["Analytics Ingestion"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectRequest"}}}},"responses":{"200":{"description":"Event accepted"},"400":{"description":"Invalid payload"},"403":{"description":"Website not found or disabled"}}},"options":{"operationId":"analyticsCollectOptions","summary":"CORS preflight for tracker","tags":["Analytics Ingestion"],"security":[],"responses":{"200":{"description":"CORS headers returned"}}}},"/api/record":{"post":{"operationId":"analyticsRecord","summary":"Ingest session replay chunks (rrweb)","description":"Accepts batched rrweb events (max 200 per request). Uses the same session\nderivation as `/api/collect`. Upserts a `ReplaySession` manifest in\nDynamoDB and queues chunks for ClickHouse via SQS topic `session_replay`.\n","tags":["Analytics Ingestion"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordRequest"}}}},"responses":{"200":{"description":"Chunk accepted"},"400":{"description":"Invalid payload"}}},"options":{"operationId":"analyticsRecordOptions","summary":"CORS preflight for recorder","tags":["Analytics Ingestion"],"security":[],"responses":{"200":{"description":"CORS headers returned"}}}},"/api/analytics/send":{"post":{"operationId":"analyticsSendLegacy","summary":"Legacy tracker ingest (Pages router)","description":"**Deprecated alias.** Same contract as `/api/collect` but served from the\nPages router at `/api/analytics/send`. New integrations should use\n`/api/collect`.\n","tags":["Analytics Ingestion"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CollectRequest"}}}},"responses":{"200":{"description":"Event accepted"}}}},"/api/posthog/decide":{"get":{"operationId":"posthogDecideGet","summary":"PostHog decide endpoint (survey matching)","description":"Implements the PostHog `decide` contract for `posthog-js` when the SDK\nis pointed at your GoOmni host. `token` is the website UUID. Returns\nactive surveys for the distinct_id. Feature flags map is empty; experiments\nuse the GrowthBook path.\n","tags":["PostHog Proxy"],"security":[],"parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"v","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Decide payload with surveys array"}}},"post":{"operationId":"posthogDecidePost","summary":"PostHog decide endpoint (POST variant)","tags":["PostHog Proxy"],"security":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","format":"uuid"},"distinct_id":{"type":"string"}}}}}},"responses":{"200":{"description":"Decide payload"}}},"options":{"operationId":"posthogDecideOptions","summary":"CORS preflight","tags":["PostHog Proxy"],"security":[],"responses":{"200":{"description":"OK"}}}},"/api/posthog/{path}":{"parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string"},"description":"Catch-all path segment (e.g. `i/v0/e`, `static/array.js`)"}],"get":{"operationId":"posthogProxyGet","summary":"PostHog SDK static assets (empty stubs)","description":"Returns harmless empty JS for `config.js` and `array.js` requests.","tags":["PostHog Proxy"],"security":[],"responses":{"200":{"description":"Empty JavaScript or JSON"}}},"post":{"operationId":"posthogProxyPost","summary":"PostHog SDK capture proxy (survey events only)","description":"Translates PostHog capture POSTs into the GoOmni ingest pipeline.\nOnly `survey shown`, `survey sent`, and `survey dismissed` events are\nstored. All other capture events are acknowledged as no-ops.\n","tags":["PostHog Proxy"],"security":[],"responses":{"200":{"description":"Acknowledged"}}},"options":{"operationId":"posthogProxyOptions","summary":"CORS preflight","tags":["PostHog Proxy"],"security":[],"responses":{"200":{"description":"OK"}}}},"/api/privacy/{websiteId}":{"parameters":[{"name":"websiteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"privacyPolicyGet","summary":"Read privacy and masking policy (tracker init)","description":"Public-readable. The tracker calls this on init to apply input masking,\ngeo-only mode, DNT respect, and performance gating before recording.\n","tags":["Analytics Privacy"],"security":[],"responses":{"200":{"description":"Privacy policy row"}}},"patch":{"operationId":"privacyPolicyPatch","summary":"Update privacy policy (admin)","description":"Requires authenticated session with org access to the website.","tags":["Analytics Privacy"],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"maskAllInputs":{"type":"integer","enum":[0,1]},"maskAllText":{"type":"integer","enum":[0,1]},"ipMasking":{"type":"integer","enum":[0,1]},"dntRespect":{"type":"integer","enum":[0,1]},"perfGateMaxMainThreadMs":{"type":"integer"}}}}}},"responses":{"200":{"description":"Updated policy"}}},"options":{"operationId":"privacyPolicyOptions","summary":"CORS preflight","tags":["Analytics Privacy"],"security":[],"responses":{"200":{"description":"OK"}}}},"/api/experiments/{experimentId}/exposure":{"parameters":[{"name":"experimentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"post":{"operationId":"experimentExposure","summary":"Record experiment exposure or conversion (tracker)","description":"Public, CORS-open. Called by the GrowthBook-powered experiment runner in\nthe tracker. Validates `variantId` against the experiment definition;\ndedup is query-side in ClickHouse.\n","tags":["Analytics Ingestion"],"security":[],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"websiteId":{"type":"string","format":"uuid"},"sessionId":{"type":"string"},"variantId":{"type":"string"},"goalName":{"type":"string","description":"When set, records a conversion for this goal."}}}}}},"responses":{"200":{"description":"Recorded"},"404":{"description":"Experiment or variant not found"}}},"options":{"operationId":"experimentExposureOptions","summary":"CORS preflight","tags":["Analytics Ingestion"],"security":[],"responses":{"200":{"description":"OK"}}}},"/api/heatmaps":{"get":{"operationId":"listHeatmaps","summary":"List heatmaps for a website","tags":["Heatmaps"],"parameters":[{"name":"websiteId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Heatmap rows","content":{"application/json":{"schema":{"type":"object","properties":{"heatmaps":{"type":"array","items":{"$ref":"#/components/schemas/Heatmap"}}}}}}}}},"post":{"operationId":"createHeatmap","summary":"Create heatmap and dispatch builder worker","tags":["Heatmaps"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["websiteId","urlPath","windowStart","windowEnd"],"properties":{"websiteId":{"type":"string","format":"uuid"},"urlPath":{"type":"string"},"device":{"type":"string","enum":["desktop","mobile","tablet"]},"viewportWidth":{"type":"integer"},"viewportHeight":{"type":"integer"},"windowStart":{"type":"string","format":"date-time"},"windowEnd":{"type":"string","format":"date-time"}}}}}},"responses":{"201":{"description":"Heatmap created (status pending)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Heatmap"}}}}}}},"/api/heatmaps/{heatmapId}":{"parameters":[{"name":"heatmapId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"getHeatmap","summary":"Get heatmap manifest and signed grid URLs","description":"Returns signed S3 URLs for screenshot, click grid, move grid, and scroll bins.","tags":["Heatmaps"],"responses":{"200":{"description":"Heatmap detail with signed asset URLs"}}},"delete":{"operationId":"deleteHeatmap","summary":"Delete heatmap","tags":["Heatmaps"],"responses":{"200":{"description":"Deleted"}}}},"/api/heatmaps/{heatmapId}/retry":{"parameters":[{"name":"heatmapId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"post":{"operationId":"retryHeatmap","summary":"Re-dispatch failed heatmap build","tags":["Heatmaps"],"responses":{"200":{"description":"Builder re-queued"}}}},"/api/replay-sessions":{"get":{"operationId":"listReplaySessions","summary":"List session replays for a website","tags":["Session Replay"],"parameters":[{"name":"websiteId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"limit","in":"query","schema":{"type":"integer","default":25,"maximum":100}},{"name":"cursor","in":"query","schema":{"type":"string"}},{"name":"hasErrors","in":"query","schema":{"type":"boolean"}},{"name":"minQuality","in":"query","schema":{"type":"integer"}},{"name":"device","in":"query","schema":{"type":"string"}},{"name":"country","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Paginated replay list","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/ReplaySessionSummary"}},"nextCursor":{"type":"string","nullable":true}}}}}}}}},"/api/replay-sessions/{replaySessionId}":{"parameters":[{"name":"replaySessionId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"operationId":"getReplaySession","summary":"Get replay manifest and rrweb events for playback","tags":["Session Replay"],"responses":{"200":{"description":"Manifest plus ordered rrweb event array from ClickHouse"}}}},"/api/experiments":{"get":{"operationId":"listExperiments","summary":"List experiments for a website","tags":["Experiments"],"parameters":[{"name":"websiteId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Experiment rows"}}},"post":{"operationId":"createExperiment","summary":"Create A/B experiment with variants and goals","tags":["Experiments"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["websiteId","name","variants"],"properties":{"websiteId":{"type":"string","format":"uuid"},"name":{"type":"string"},"hypothesis":{"type":"string"},"variants":{"type":"array","items":{"type":"object"}},"goals":{"type":"array","items":{"type":"object"}}}}}}},"responses":{"201":{"description":"Experiment created"}}}},"/api/experiments/{experimentId}":{"parameters":[{"name":"experimentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"getExperiment","summary":"Get experiment definition","tags":["Experiments"],"responses":{"200":{"description":"Experiment detail"}}},"patch":{"operationId":"updateExperiment","summary":"Update experiment (status, variants, targeting)","tags":["Experiments"],"responses":{"200":{"description":"Updated"}}},"delete":{"operationId":"deleteExperiment","summary":"Archive experiment","tags":["Experiments"],"responses":{"200":{"description":"Deleted"}}}},"/api/experiments/{experimentId}/results":{"parameters":[{"name":"experimentId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"getExperimentResults","summary":"Get variant stats snapshot","description":"Pass `refresh=true` to recompute stats in-band (5s cap).","tags":["Experiments"],"parameters":[{"name":"refresh","in":"query","schema":{"type":"boolean"}}],"responses":{"200":{"description":"latestStats plus variant definitions"}}}},"/api/surveys":{"get":{"operationId":"listSurveys","summary":"List surveys for a website","tags":["Surveys"],"parameters":[{"name":"websiteId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Survey rows"}}},"post":{"operationId":"createSurvey","summary":"Create in-product survey (PostHog-compatible shape)","tags":["Surveys"],"responses":{"201":{"description":"Survey created"}}}},"/api/surveys/{surveyId}":{"parameters":[{"name":"surveyId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"getSurvey","summary":"Get survey definition","tags":["Surveys"],"responses":{"200":{"description":"Survey detail"}}},"patch":{"operationId":"updateSurvey","summary":"Update survey","tags":["Surveys"],"responses":{"200":{"description":"Updated"}}},"delete":{"operationId":"deleteSurvey","summary":"Delete survey","tags":["Surveys"],"responses":{"200":{"description":"Deleted"}}}},"/api/forms":{"get":{"operationId":"listFormAnalytics","summary":"List form field analytics aggregates","description":"Form submissions and field-level metrics are ingested as custom events\nthrough `/api/collect`. This endpoint returns aggregated field stats.\n","tags":["Forms Analytics"],"parameters":[{"name":"websiteId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Form analytics rows"}}}},"/api/guided-flows":{"get":{"operationId":"listGuidedFlows","summary":"List guided product tours for a website","tags":["Guided Flows"],"parameters":[{"name":"websiteId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Guided flow rows"}}},"post":{"operationId":"createGuidedFlow","summary":"Create guided flow","tags":["Guided Flows"],"responses":{"201":{"description":"Flow created"}}}},"/api/guided-flows/active":{"get":{"operationId":"getActiveGuidedFlows","summary":"Active flows for tracker (public)","description":"CORS-open. Returns running guided flows for the website key.","tags":["Guided Flows"],"security":[],"parameters":[{"name":"websiteId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Active flow configs"}}}},"/api/guided-flows/{flowId}":{"parameters":[{"name":"flowId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"getGuidedFlow","summary":"Get guided flow","tags":["Guided Flows"],"responses":{"200":{"description":"Flow detail"}}},"patch":{"operationId":"updateGuidedFlow","summary":"Update guided flow","tags":["Guided Flows"],"responses":{"200":{"description":"Updated"}}},"delete":{"operationId":"deleteGuidedFlow","summary":"Delete guided flow","tags":["Guided Flows"],"responses":{"200":{"description":"Deleted"}}}},"/api/analytics/websites":{"get":{"operationId":"analyticsListWebsites","summary":"List websites for the authenticated user","tags":["Analytics Websites"],"responses":{"200":{"description":"Paginated website list"}}},"post":{"operationId":"analyticsCreateWebsite","summary":"Create analytics website (tracker site key)","tags":["Analytics Websites"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"domain":{"type":"string"},"teamId":{"type":"string"},"shareId":{"type":"string"}}}}}},"responses":{"201":{"description":"Website created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsWebsite"}}}}}}},"/api/analytics/websites/{websiteId}":{"parameters":[{"name":"websiteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"analyticsGetWebsite","summary":"Get website details","tags":["Analytics Websites"],"responses":{"200":{"description":"Website row"}}},"patch":{"operationId":"analyticsUpdateWebsite","summary":"Update website name, domain, or settings","tags":["Analytics Websites"],"responses":{"200":{"description":"Updated"}}},"delete":{"operationId":"analyticsDeleteWebsite","summary":"Delete website and associated data","tags":["Analytics Websites"],"responses":{"200":{"description":"Deleted"}}}},"/api/analytics/websites/{websiteId}/stats":{"parameters":[{"name":"websiteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"analyticsWebsiteStats","summary":"Summary stats for a date range","description":"Core dashboard KPIs: pageviews, visitors, visits, bounces, totaltime.\nSupports dimensional filters (url, referrer, browser, device, country, etc.)\nand `compare` for period-over-period.\n\n**Query:** ClickHouse `website_event`, grouped by session/visit.\nSource: `src/analytics/queries/analytics/getWebsiteStats.ts`.\nPage builder `queryName`: `stats`.\n","tags":["Analytics Metrics"],"parameters":[{"name":"startAt","in":"query","required":true,"schema":{"type":"integer","description":"Unix timestamp (ms)"}},{"name":"endAt","in":"query","required":true,"schema":{"type":"integer"}},{"name":"url","in":"query","schema":{"type":"string"}},{"name":"device","in":"query","schema":{"type":"string"}},{"name":"country","in":"query","schema":{"type":"string"}},{"name":"compare","in":"query","schema":{"type":"string","description":"Previous period token for delta columns."}}],"responses":{"200":{"description":"Stats object with totals and compare deltas"}}}},"/api/analytics/websites/{websiteId}/metrics":{"parameters":[{"name":"websiteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"analyticsWebsiteMetrics","summary":"Ranked breakdown by dimension (url, referrer, device, country, etc.)","description":"Returns `{x, y}` rows: dimension value and count. Used for top pages,\nreferrers, device breakdown, and similar tables.\n\n**Query:** `SELECT dimension, count(*) FROM website_event GROUP BY dimension`.\nSource: `src/analytics/queries/analytics/pageviews/getPageviewMetrics.ts`\n(event columns) or `sessions/getSessionMetrics.ts` (session columns).\nPage builder: `topPages` (`type=url`), `referrers` (`type=referrer`),\n`deviceBreakdown` (`type=device`).\n","tags":["Analytics Metrics"],"parameters":[{"name":"startAt","in":"query","required":true,"schema":{"type":"integer"}},{"name":"endAt","in":"query","required":true,"schema":{"type":"integer"}},{"name":"type","in":"query","schema":{"type":"string","enum":["pageview","session","bounce","totaltime"]}},{"name":"unit","in":"query","schema":{"type":"string","enum":["minute","hour","day","month","year"]}}],"responses":{"200":{"description":"Array of `{x, y}` points"}}}},"/api/analytics/websites/{websiteId}/pageviews":{"parameters":[{"name":"websiteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"analyticsWebsitePageviews","summary":"Pageviews and sessions time series","description":"Chart data: pageview and session counts bucketed by hour/day/month.\n\n**Query:** `website_event` aggregated over time.\nSource: `src/analytics/queries/analytics/pageviews/getPageviewStats.ts`.\nPage builder: `pageViews`, `sessions`.\n","tags":["Analytics Metrics"],"responses":{"200":{"description":"Time series with pageviews and sessions axes"}}}},"/api/analytics/websites/{websiteId}/events":{"parameters":[{"name":"websiteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"analyticsWebsiteEvents","summary":"Custom event breakdown","tags":["Analytics Metrics"],"responses":{"200":{"description":"Event name counts"}}}},"/api/analytics/realtime/{websiteId}":{"parameters":[{"name":"websiteId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"analyticsRealtime","summary":"Active visitors in the last 30 minutes","tags":["Analytics Realtime"],"responses":{"200":{"description":"Realtime counts and recent pageviews"}}}},"/api/analytics/reports":{"get":{"operationId":"analyticsListReports","summary":"List saved and built-in report types","tags":["Analytics Reports"],"responses":{"200":{"description":"Report catalog"}}}},"/api/analytics/reports/funnel":{"post":{"operationId":"analyticsReportFunnel","summary":"Funnel conversion report","description":"Ordered step conversion. Body: `websiteId`, `steps` (URL or event per step),\n`window` (minutes between steps), `dateRange`.\n\n**Query:** sessions that hit step 1, then 2, then 3 in order within the window.\nSource: `src/analytics/queries/analytics/reports/getFunnel.ts`.\nPage builder `queryName`: `funnel`.\nSee also: `/api-docs/analytics-reports`.\n","tags":["Analytics Reports"],"responses":{"200":{"description":"Funnel steps with visitors, dropoff, and remaining rate"}}}},"/api/analytics/reports/retention":{"post":{"operationId":"analyticsReportRetention","summary":"Cohort retention report","description":"First-visit cohorts by day and return rate on subsequent days.\n\n**Query:** cohort assignment from first `website_event`, then return visits.\nSource: `src/analytics/queries/analytics/reports/getRetention.ts`.\nPage builder `queryName`: `retention`.\n","tags":["Analytics Reports"],"responses":{"200":{"description":"Retention matrix by cohort date and day offset"}}}},"/api/analytics/reports/insights":{"post":{"operationId":"analyticsReportInsights","summary":"Dimensional insights breakdown","description":"Views, visitors, visits, bounces, and time grouped by a chosen field.\n\nSource: `src/analytics/queries/analytics/reports/getInsights.ts`.\n","tags":["Analytics Reports"],"responses":{"200":{"description":"Ranked breakdown rows"}}}},"/api/analytics/reports/goals":{"post":{"operationId":"analyticsReportGoals","summary":"Goal completion report","description":"Counts of named goal events (custom events marked as goals).\n\nSource: `src/analytics/queries/analytics/reports/getGoals.ts`.\n","tags":["Analytics Reports"],"responses":{"200":{"description":"Goal hits by name"}}}},"/api/analytics/reports/journey":{"post":{"operationId":"analyticsReportJourney","summary":"User journey paths report","description":"Common sequences of pages within a session.\n\nSource: `src/analytics/queries/analytics/reports/getJourney.ts`.\n","tags":["Analytics Reports"],"responses":{"200":{"description":"Sankey-style path data"}}}},"/api/analytics/reports/utm":{"post":{"operationId":"analyticsReportUtm","summary":"UTM campaign breakdown","description":"Traffic grouped by utm_source, utm_medium, utm_campaign.\n\nSource: `src/analytics/queries/analytics/reports/getUTM.ts`.\n","tags":["Analytics Reports"],"responses":{"200":{"description":"UTM dimension rows"}}}},"/api/analytics/reports/revenue":{"post":{"operationId":"analyticsReportRevenue","summary":"Revenue attribution report","description":"Revenue totals tied to events or user properties over a date range.\n\nSource: `src/analytics/queries/analytics/reports/getRevenue.ts`.\n","tags":["Analytics Reports"],"responses":{"200":{"description":"Revenue time series or breakdown"}}}},"/api/analytics/me":{"get":{"operationId":"analyticsMe","summary":"Current analytics user profile","tags":["Analytics Teams"],"responses":{"200":{"description":"User id, role, teams"}}}},"/api/analytics/teams":{"get":{"operationId":"analyticsListTeams","summary":"List teams","tags":["Analytics Teams"],"responses":{"200":{"description":"Team list"}}},"post":{"operationId":"analyticsCreateTeam","summary":"Create team","tags":["Analytics Teams"],"responses":{"201":{"description":"Team created"}}}},"/api/analytics/teams/{teamId}/websites":{"parameters":[{"name":"teamId","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"get":{"operationId":"analyticsTeamWebsites","summary":"List websites shared with a team","tags":["Analytics Teams"],"responses":{"200":{"description":"Website list"}}}},"/api/analytics/event-data/fields":{"get":{"operationId":"analyticsEventDataFields","summary":"Discover custom event property keys","tags":["Analytics Metrics"],"parameters":[{"name":"websiteId","in":"query","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Field names and sample values"}}}},"/api/analytics/share/{shareId}":{"parameters":[{"name":"shareId","in":"path","required":true,"schema":{"type":"string"}}],"get":{"operationId":"analyticsPublicShare","summary":"Public read-only dashboard by share token","description":"No auth when `shareId` is enabled on the website.","tags":["Analytics Websites"],"security":[],"responses":{"200":{"description":"Shared stats payload"}}}},"/api/analytics/heartbeat":{"get":{"operationId":"analyticsHeartbeat","summary":"Health check for analytics API","tags":["Analytics Websites"],"security":[],"responses":{"200":{"description":"OK"}}}}}}