{"openapi":"3.0.0","info":{"title":"Scrubbe API","version":"1.0.0","description":"Scrubbe Incident Management System — comprehensive backend API for incident tracking, fraud detection, and security operations.","contact":{"name":"Scrubbe Dev Team","email":"scrubbe.dev@gmail.com","url":"https://scrubbe.com"},"license":{"name":"MIT","url":"https://opensource.org/licenses/MIT"}},"servers":[{"url":"http://localhost:5000/api/v1","description":"Development server"},{"url":"https://scrubbe-server-9z77.onrender.com/api/v1","description":"Production server"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Enter your JWT access token"},"apiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API Key for programmatic access"}},"schemas":{"SuccessResponse":{"type":"object","properties":{"success":{"type":"boolean","example":true},"message":{"type":"string","example":"Operation successful"},"data":{"type":"object"}}},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","example":false},"message":{"type":"string","example":"An error occurred"},"errors":{"type":"array","items":{"type":"string"}}}},"PaginationMeta":{"type":"object","properties":{"total":{"type":"integer"},"page":{"type":"integer"},"limit":{"type":"integer"},"totalPages":{"type":"integer"}}},"User":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"email":{"type":"string","format":"email"},"firstName":{"type":"string"},"lastName":{"type":"string"},"isVerified":{"type":"boolean"},"accountType":{"type":"string","enum":["DEVELOPER","BUSINESS"]},"businessId":{"type":"string","nullable":true},"roles":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"}}},"AuthTokens":{"type":"object","properties":{"accessToken":{"type":"string"},"refreshToken":{"type":"string"}}},"AuthResponse":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/User"},"tokens":{"$ref":"#/components/schemas/AuthTokens"}}},"IncidentTicket":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"ticketId":{"type":"string"},"summary":{"type":"string"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"status":{"type":"string","enum":["OPEN","ACKNOWLEDGED","INVESTIGATION","MITIGATED","RESOLVED","CLOSED"]},"assignedToEmail":{"type":"string"},"businessId":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}},"security":[{"bearerAuth":[]}],"tags":[{"name":"Auth","description":"Authentication & authorization endpoints"},{"name":"Business","description":"Business setup & team management"},{"name":"IMS","description":"Incident Management System setup"},{"name":"Incident Tickets","description":"Incident ticket CRUD & operations"},{"name":"Dashboard","description":"Dashboard metrics & analytics"},{"name":"API Keys","description":"API key management"},{"name":"Integrations","description":"Third-party integrations (Slack, GitHub, GitLab, etc.)"},{"name":"Pricing","description":"Subscription plans & Stripe billing"},{"name":"Customer Portal","description":"External customer incident portal"},{"name":"On-Call","description":"On-call schedule management"},{"name":"Admin","description":"Admin panel (blogs, careers, users)"},{"name":"Fingerprint","description":"Device fingerprint configuration"},{"name":"AI","description":"AI-powered incident analysis & suggestions"},{"name":"Postmortem","description":"Post-mortem report generation"},{"name":"Ezra","description":"Ezra — Scrubbe's intelligence layer. Reads incidents, reasons over them, and explains them to the right person."},{"name":"Ingestion","description":"Event ingestion — normalise, deduplicate, and route events from external sources into the Scrubbe pipeline."}],"paths":{"/api/v1/ezra/analyse":{"post":{"summary":"Run Ezra's 4-stage reasoning pipeline over an incident","tags":["Ezra"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["incidentId"],"properties":{"incidentId":{"type":"string"}}}}}},"responses":{"200":{"description":"Structured analysis with hypothesis, impact, and remediation options"}}}},"/api/v1/ezra/analyses":{"get":{"summary":"List all Ezra analyses for the business","tags":["Ezra"],"parameters":[{"in":"query","name":"page","schema":{"type":"integer","default":1}},{"in":"query","name":"limit","schema":{"type":"integer","default":20}}]}},"/api/v1/ezra/analysis/{incidentId}":{"get":{"summary":"Fetch the latest Ezra analysis for an incident, with all generated reports","tags":["Ezra"],"parameters":[{"in":"path","name":"incidentId","required":true,"schema":{"type":"string"}}]}},"/api/v1/ezra/report":{"post":{"summary":"Generate an LLM-narrated report for ENGINEER or LEADERSHIP audience","tags":["Ezra"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["analysisId","audience"],"properties":{"analysisId":{"type":"string"},"audience":{"type":"string","enum":["ENGINEER","LEADERSHIP"]}}}}}}}},"/api/v1/ezra/learn":{"post":{"summary":"Record an incident outcome so Ezra can update its pattern memory","tags":["Ezra"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["incidentId","outcome"],"properties":{"incidentId":{"type":"string"},"outcome":{"type":"string","enum":["RESOLVED","DEGRADED","NEUTRAL","WORSENED"]}}}}}}}},"/api/v1/ezra/patterns":{"get":{"summary":"List all learned signal patterns for the business","tags":["Ezra"]}},"/api/v1/ingestion/kubernetes/manifest":{"get":{"summary":"Download the Scrubbe Kubernetes ingestion agent manifest","tags":["Ingestion"]}},"/api/v1/ingestion/github":{"post":{"summary":"Receive GitHub Actions / deployment_status webhooks","tags":["Ingestion"],"security":[{"apiKey":[]}]}},"/api/v1/ingestion/gitlab":{"post":{"summary":"Receive GitLab pipeline webhooks","tags":["Ingestion"],"security":[{"apiKey":[]}]}},"/api/v1/ingestion/bitbucket":{"post":{"summary":"Receive Bitbucket Pipelines / deployment webhooks","tags":["Ingestion"]}},"/api/v1/ingestion/kubernetes":{"post":{"summary":"Receive Kubernetes pod crash / restart webhooks","tags":["Ingestion"],"security":[{"apiKey":[]}]}},"/api/v1/ingestion/pagerduty":{"post":{"summary":"Receive PagerDuty V2 incident webhooks","tags":["Ingestion"],"security":[{"apiKey":[]}]}},"/api/v1/ingestion/prometheus":{"post":{"summary":"Receive Prometheus Alertmanager webhooks","tags":["Ingestion"],"security":[{"apiKey":[]}]}},"/api/v1/ingestion/datadog":{"post":{"summary":"Receive Datadog alert webhooks","tags":["Ingestion"],"security":[{"apiKey":[]}]}},"/api/v1/ingestion/webhook":{"post":{"summary":"Generic inbound webhook (Scrubbe canonical payload)","tags":["Ingestion"],"security":[{"apiKey":[]}]}},"/incident-ticket/resolve/ai/five-whys/{id}":{"get":{"tags":["AI"],"summary":"Generate AI-powered 5-Whys root cause analysis","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}]}},"/incident-ticket/resolve/ai/suggestion/{id}":{"get":{"tags":["AI"],"summary":"Get AI-powered remediation suggestions"}},"/incident-ticket/resolve/ai/stakeholder/{id}":{"get":{"tags":["AI"],"summary":"Generate AI stakeholder communication message"}},"/generate-pdf":{"post":{"tags":["AI"],"summary":"Generate PDF report for an incident/RCA","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"description":{"type":"string"}}}}}},"responses":{"200":{"description":"PDF file","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}}}}},"/apikey/createapikey":{"post":{"tags":["API Keys"],"summary":"Create a new API key","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","environment"],"properties":{"name":{"type":"string"},"environment":{"type":"string","enum":["PRODUCTION","DEVELOPMENT"]},"scopes":{"type":"array","items":{"type":"string"}}}}}}},"responses":{"201":{"description":"API key created (raw key shown only once)"}}}},"/apikey/apikeys":{"get":{"tags":["API Keys"],"summary":"Get all API keys for the authenticated user","responses":{"200":{"description":"List of API keys"}}}},"/apikey/{id}/rotate":{"post":{"tags":["API Keys"],"summary":"Rotate (regenerate) an API key"}},"/apikey/{id}/revoke":{"post":{"tags":["API Keys"],"summary":"Revoke (deactivate) an API key"}},"/apikey/{id}":{"delete":{"tags":["API Keys"],"summary":"Delete an API key"}},"/auth/login":{"post":{"tags":["Auth"],"summary":"Login with email and password","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password"],"properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"}}}}}},"responses":{"200":{"description":"Login successful","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthResponse"}}}},"401":{"description":"Invalid credentials"}}}},"/auth/oauth/login":{"post":{"tags":["Auth"],"summary":"OAuth login","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","provider_uuid","oAuthProvider"],"properties":{"email":{"type":"string"},"provider_uuid":{"type":"string"},"oAuthProvider":{"type":"string"}}}}}},"responses":{"200":{"description":"OAuth login successful"}}}},"/auth/sso/discovery":{"get":{"tags":["Auth"],"summary":"Discover SSO settings for an email address","security":[],"parameters":[{"in":"query","name":"email","required":true,"schema":{"type":"string","format":"email"}}]}},"/auth/dev/register":{"post":{"tags":["Auth"],"summary":"Register a developer account","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["firstName","lastName","email","password","experienceLevel"],"properties":{"firstName":{"type":"string"},"lastName":{"type":"string"},"email":{"type":"string"},"password":{"type":"string"},"githubUsername":{"type":"string"},"experienceLevel":{"type":"string"}}}}}},"responses":{"201":{"description":"Developer account created"}}}},"/auth/business/register":{"post":{"tags":["Auth"],"summary":"Register a business account","security":[]}},"/auth/oauth/dev/register":{"post":{"tags":["Auth"],"summary":"Register a developer account via OAuth","security":[]}},"/auth/oauth/business/register":{"post":{"tags":["Auth"],"summary":"Register a business account via OAuth","security":[]}},"/auth/verify_email":{"post":{"tags":["Auth"],"summary":"Verify email with OTP","security":[]}},"/auth/resend_otp":{"post":{"tags":["Auth"],"summary":"Resend email verification OTP","security":[]}},"/auth/forgot-password":{"post":{"tags":["Auth"],"summary":"Request a password reset link","security":[]}},"/auth/magic-link":{"post":{"tags":["Auth"],"summary":"Send a magic sign-in link to the user's email","security":[]}},"/auth/magic-link/consume":{"post":{"tags":["Auth"],"summary":"Consume a magic link token and create an authenticated session","security":[]}},"/auth/validate-reset-token":{"post":{"tags":["Auth"],"summary":"Validate a password reset token","security":[]}},"/auth/reset-password":{"post":{"tags":["Auth"],"summary":"Reset password with token","security":[]}},"/auth/change-password":{"post":{"tags":["Auth"],"summary":"Change password (authenticated)"}},"/auth/refresh-token":{"post":{"tags":["Auth"],"summary":"Refresh access token","security":[]}},"/auth/logout":{"post":{"tags":["Auth"],"summary":"Logout and invalidate refresh token"}},"/auth/me":{"get":{"tags":["Auth"],"summary":"Get current authenticated user","responses":{"200":{"description":"Current user data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/User"}}}}}}},"/business/setup":{"put":{"tags":["Business"],"summary":"Complete business setup/profile","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"businessName":{"type":"string"},"industry":{"type":"string"},"website":{"type":"string"},"address":{"type":"string"},"companySize":{"type":"string"}}}}}},"responses":{"200":{"description":"Business setup completed"}}}},"/business/get_members":{"get":{"tags":["Business"],"summary":"Get all team members of the business","responses":{"200":{"description":"List of team members"}}}},"/business/send-invite":{"post":{"tags":["Business"],"summary":"Send team member invitation email","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","role"],"properties":{"email":{"type":"string"},"role":{"type":"string"},"accessPermissions":{"type":"array","items":{"type":"string"}},"level":{"type":"string"}}}}}},"responses":{"200":{"description":"Invitation sent"}}}},"/business/decode-invite":{"post":{"tags":["Business"],"summary":"Decode invitation token to get invite details","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string"}}}}}}}},"/business/accept-invite":{"post":{"tags":["Business"],"summary":"Accept a team invitation and create account","security":[]}},"/customer/companies":{"get":{"tags":["Customer Portal"],"summary":"Get list of companies on Scrubbe","security":[]}},"/customer/register":{"post":{"tags":["Customer Portal"],"summary":"Register as a customer for a company","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email","password","businessId"],"properties":{"email":{"type":"string"},"name":{"type":"string"},"password":{"type":"string"},"businessId":{"type":"string"}}}}}}}},"/customer/login":{"post":{"tags":["Customer Portal"],"summary":"Customer login","security":[]}},"/customer/create-incident":{"post":{"tags":["Customer Portal"],"summary":"Create a new customer incident"}},"/customer/get-incident/{id}":{"get":{"tags":["Customer Portal"],"summary":"Get a specific customer incident"}},"/customer/get-incidents":{"get":{"tags":["Customer Portal"],"summary":"Get all incidents for the logged-in customer"}},"/dashboard/metrics":{"get":{"tags":["Dashboard"],"summary":"Get key dashboard metrics (MTTA, MTTR, SLA compliance, open incidents)","responses":{"200":{"description":"Dashboard metrics"}}}},"/dashboard/analytics":{"get":{"tags":["Dashboard"],"summary":"Get dashboard analytics (trends, workload, recurring issues)","responses":{"200":{"description":"Dashboard analytics"}}}},"/fingerprint/system-info":{"get":{"tags":["Fingerprint"],"summary":"Collect browser and network system info for the current request"}},"/fingerprint/configuration":{"get":{"tags":["Fingerprint"],"summary":"Get fingerprint configuration for the business"},"post":{"tags":["Fingerprint"],"summary":"Save fingerprint configuration","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"enabled":{"type":"boolean"},"captureDeviceId":{"type":"boolean"},"captureIp":{"type":"boolean"},"captureLocation":{"type":"boolean"}}}}}}}},"/ims/setup":{"post":{"tags":["IMS"],"summary":"Setup or update IMS configuration","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"alertEmail":{"type":"string"},"slackChannel":{"type":"string"},"slaEnabled":{"type":"boolean"},"autoEscalate":{"type":"boolean"},"notifyOnCreate":{"type":"boolean"},"notifyOnResolve":{"type":"boolean"},"timezone":{"type":"string"}}}}}},"responses":{"200":{"description":"IMS configuration saved"}}}},"/incident-ticket/generate-id":{"get":{"tags":["Incident Tickets"],"summary":"Generate a unique incident ticket ID","responses":{"200":{"description":"Generated ticket ID"}}}},"/incident-ticket":{"post":{"tags":["Incident Tickets"],"summary":"Create a new incident ticket","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["summary","priority"],"properties":{"summary":{"type":"string"},"priority":{"type":"string","enum":["LOW","MEDIUM","HIGH","CRITICAL"]},"techDescription":{"type":"string"},"category":{"type":"string"},"affectedSystem":{"type":"string"},"assignedToEmail":{"type":"string"}}}}}},"responses":{"201":{"description":"Incident ticket created"}}},"get":{"tags":["Incident Tickets"],"summary":"Get all incident tickets for the business","parameters":[{"in":"query","name":"page","schema":{"type":"integer"}},{"in":"query","name":"limit","schema":{"type":"integer"}},{"in":"query","name":"status","schema":{"type":"string"}},{"in":"query","name":"priority","schema":{"type":"string"}},{"in":"query","name":"search","schema":{"type":"string"}}],"responses":{"200":{"description":"List of incident tickets"}}}},"/incident-ticket/{id}":{"get":{"tags":["Incident Tickets"],"summary":"Get a specific incident ticket","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}]},"put":{"tags":["Incident Tickets"],"summary":"Update an incident ticket"},"delete":{"tags":["Incident Tickets"],"summary":"Delete an incident ticket"}},"/incident-ticket/comment":{"post":{"tags":["Incident Tickets"],"summary":"Add a comment to a ticket","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ticketId","content"],"properties":{"ticketId":{"type":"string"},"content":{"type":"string"},"isInternal":{"type":"boolean"}}}}}}}},"/incident-ticket/comment/{ticketId}":{"get":{"tags":["Incident Tickets"],"summary":"Get all comments for a ticket"}},"/incident-ticket/message/{ticketId}":{"get":{"tags":["Incident Tickets"],"summary":"Get all messages for a ticket"}},"/incident-ticket/analytics":{"get":{"tags":["Incident Tickets"],"summary":"Get incident analytics for the business"}},"/postmortems":{"get":{"tags":["Postmortem"],"summary":"Get all post-mortems for the business"}},"/incident-ticket/resolve/{id}":{"post":{"tags":["Postmortem"],"summary":"Resolve an incident with post-mortem data","parameters":[{"in":"path","name":"id","required":true,"schema":{"type":"string"}}]}},"/incident-ticket/resolve/customer-kb/{id}":{"post":{"tags":["Postmortem"],"summary":"Publish customer-facing knowledge base article"}},"/tickets/history":{"get":{"tags":["Incident Tickets"],"summary":"Get incident history/audit trail"}},"/integrations/{userId}":{"get":{"tags":["Integrations"],"summary":"Get all active integrations for a user"}},"/assign-member":{"post":{"tags":["On-Call"],"summary":"Assign team members to on-call schedule","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["date","teamMembers"],"properties":{"date":{"type":"string","example":"2025-03-10"},"teamMembers":{"type":"array","items":{"type":"object","properties":{"userId":{"type":"string"},"startTime":{"type":"string"},"endTime":{"type":"string"}}}}}}}}}}},"/get-all-assign":{"get":{"tags":["On-Call"],"summary":"Get all on-call schedules"}},"/get-assign/{id}":{"get":{"tags":["On-Call"],"summary":"Get a specific on-call schedule"}},"/pricing/plans":{"get":{"tags":["Pricing"],"summary":"Get all available subscription plans","security":[]}},"/pricing/checkout/create-session":{"post":{"tags":["Pricing"],"summary":"Create Stripe checkout session","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["planId"],"properties":{"planId":{"type":"string"},"successUrl":{"type":"string"},"cancelUrl":{"type":"string"}}}}}}}},"/pricing/subscriptions":{"post":{"tags":["Pricing"],"summary":"Create a manual subscription"}},"/pricing/customers/{userId}/subscriptions":{"get":{"tags":["Pricing"],"summary":"Get user's active subscription"}}}}