{"openapi":"3.1.0","info":{"title":"Realific API","version":"1.0.0","description":"Privacy-first, revenue-aware web analytics. Public API under /v1, app API under /app, webhooks under /webhooks, share links under /share."},"servers":[{"url":"https://api.realific.app"},{"url":"https://api.realific.app"}],"tags":[{"name":"Auth"},{"name":"Orgs"},{"name":"Workspaces"},{"name":"Members"},{"name":"API keys"},{"name":"Billing"},{"name":"Sites"},{"name":"Goals"},{"name":"Funnels"},{"name":"Annotations"},{"name":"Share links"},{"name":"Reports"},{"name":"Alerts"},{"name":"Integrations"},{"name":"Exports"},{"name":"Stats"},{"name":"Revenue"},{"name":"Customers"},{"name":"Ingestion"},{"name":"Webhooks"},{"name":"Share"},{"name":"Realtime"},{"name":"System"}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","bearerFormat":"rf_live_… API key","description":"API key with scopes stats:read, events:write, sites:write, payments:write"},"cookie":{"type":"apiKey","in":"cookie","name":"rf_session","description":"Session cookie; non-GET requests also need X-CSRF-Token = rf_csrf cookie"}},"schemas":{"User":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"},"avatar_url":{"type":["string","null"]},"last_org_id":{"type":["string","null"]},"last_site_id":{"type":["string","null"]}},"required":["id","email","name","avatar_url","last_org_id","last_site_id"]},"OrgSummary":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"plan":{"type":"string"},"role":{"type":"string"},"trial_ends_at":{"type":["number","null"]}},"required":["id","name","slug","plan","role","trial_ends_at"]},"Workspace":{"type":"object","properties":{"id":{"type":"string"},"org_id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"is_client":{"type":"boolean"},"created_at":{"type":"number"},"sites_count":{"type":"number"}},"required":["id","org_id","name","slug","is_client","created_at","sites_count"]},"ApiError":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"},"details":{}},"required":["code","message","request_id"]}},"required":["error"]},"PlanLimits":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"null"}]}},"OrgDetail":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"plan":{"type":"string"},"plan_interval":{"type":["string","null"]},"trial_ends_at":{"type":["number","null"]},"white_label":{"type":"object","properties":{"logo_url":{"type":["string","null"]},"accent":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["logo_url","accent","name"]},"usage":{"type":"object","properties":{"events":{"type":"number"},"quota":{"type":"number"},"month":{"type":"string"},"warned":{"type":"boolean"}},"required":["events","quota","month","warned"]},"limits":{"$ref":"#/components/schemas/PlanLimits"},"role":{"type":"string"}},"required":["id","name","slug","plan","plan_interval","trial_ends_at","white_label","usage","limits","role"]},"Member":{"type":"object","properties":{"user_id":{"type":"string"},"email":{"type":"string"},"name":{"type":["string","null"]},"avatar_url":{"type":["string","null"]},"role":{"type":"string"},"workspace_id":{"type":["string","null"]},"site_ids":{"type":["array","null"],"items":{"type":"string"}},"created_at":{"type":"number"}},"required":["user_id","email","name","avatar_url","role","workspace_id","site_ids","created_at"]},"Invite":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"},"workspace_id":{"type":["string","null"]},"expires_at":{"type":"number"}},"required":["id","email","role","workspace_id","expires_at"]},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string"},"scopes":{"type":"array","items":{"type":"string"}},"site_id":{"type":["string","null"]},"last_used_at":{"type":["number","null"]},"created_at":{"type":"number"}},"required":["id","name","prefix","scopes","site_id","last_used_at","created_at"]},"Billing":{"type":"object","properties":{"plan":{"type":"string"},"status":{"type":"string","enum":["trialing","active","past_due","canceling","expired"]},"plan_interval":{"type":["string","null"]},"tier":{"type":["string","null"]},"trial_ends_at":{"type":["number","null"]},"current_period_end":{"type":["number","null"]},"has_billing_customer":{"type":"boolean"},"usage":{"type":"object","properties":{"events":{"type":"number"},"quota":{"type":"number"},"period_start":{"type":"number"},"period_end":{"type":"number"},"percent":{"type":"number"},"grace_until":{"type":["number","null"]}},"required":["events","quota","period_start","period_end","percent","grace_until"]},"invoices":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"amount_cents":{"type":"number"},"currency":{"type":"string"},"status":{"type":"string"},"created":{"type":"number"},"url":{"type":["string","null"]}},"required":["id","amount_cents","currency","status","created","url"]}},"plans":{"type":"object","additionalProperties":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"null"}]}}},"tiers":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"events":{"type":"number"},"starter":{"type":"number"},"growth":{"type":"number"}},"required":["id","label","events","starter","growth"]}},"trial_days":{"type":"number"},"yearly_months_charged":{"type":"number"}},"required":["plan","status","plan_interval","tier","trial_ends_at","current_period_end","has_billing_customer","usage","invoices","plans","tiers","trial_days","yearly_months_charged"]},"SiteSettings":{"type":"object","properties":{"track_outbound":{"type":"boolean"},"track_downloads":{"type":"boolean"},"hash_routing":{"type":"boolean"},"allowed_domains":{"type":"array","items":{"type":"string"}},"exclude_paths":{"type":"array","items":{"type":"string"}},"exclude_ips":{"type":"array","items":{"type":"string"}},"exclude_countries":{"type":"array","items":{"type":"string"}},"respect_dnt":{"type":"boolean"},"custom_domain":{"type":["string","null"]}},"required":["track_outbound","track_downloads","hash_routing","allowed_domains","exclude_paths","exclude_ips","exclude_countries","respect_dnt","custom_domain"]},"Site":{"type":"object","properties":{"id":{"type":"string"},"workspace_id":{"type":"string"},"org_id":{"type":"string"},"domain":{"type":"string"},"name":{"type":"string"},"timezone":{"type":"string"},"currency":{"type":"string"},"public_key":{"type":"string"},"cookieless":{"type":"boolean"},"settings":{"$ref":"#/components/schemas/SiteSettings"},"created_at":{"type":"number"}},"required":["id","workspace_id","org_id","domain","name","timezone","currency","public_key","cookieless","settings","created_at"]},"SiteDetail":{"allOf":[{"$ref":"#/components/schemas/Site"},{"type":"object","properties":{"first_event_at":{"type":["number","null"]},"installed":{"type":"boolean"},"snippet":{"type":"string"}},"required":["first_event_at","installed","snippet"]}]},"Goal":{"type":"object","properties":{"id":{"type":"string"},"site_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["pageview","event","revenue"]},"match":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["pageview"]},"path":{"type":"string"}},"required":["type","path"]},{"type":"object","properties":{"type":{"type":"string","enum":["event"]},"name":{"type":"string"},"prop_key":{"type":"string"},"prop_value":{"type":"string"}},"required":["type","name"]},{"type":"object","properties":{"type":{"type":"string","enum":["revenue"]}},"required":["type"]}]},"created_at":{"type":"number"}},"required":["id","site_id","name","type","match","created_at"]},"Funnel":{"type":"object","properties":{"id":{"type":"string"},"site_id":{"type":"string"},"name":{"type":"string"},"steps":{"type":"array","items":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["pageview"]},"path":{"type":"string"},"label":{"type":"string"}},"required":["type","path"]},{"type":"object","properties":{"type":{"type":"string","enum":["event"]},"name":{"type":"string"},"label":{"type":"string"}},"required":["type","name"]},{"type":"object","properties":{"type":{"type":"string","enum":["goal"]},"goal_id":{"type":"string"},"label":{"type":"string"}},"required":["type","goal_id"]}]}},"window_sec":{"type":"number"}},"required":["id","site_id","name","steps","window_sec"]},"Annotation":{"type":"object","properties":{"id":{"type":"string"},"ts":{"type":"number"},"label":{"type":"string"},"source":{"type":"string"}},"required":["id","ts","label","source"]},"ShareLink":{"type":"object","properties":{"id":{"type":"string"},"site_id":{"type":"string"},"slug":{"type":"string"},"has_password":{"type":"boolean"},"hide_revenue":{"type":"boolean"},"expires_at":{"type":["number","null"]},"url":{"type":"string"}},"required":["id","site_id","slug","has_password","hide_revenue","expires_at","url"]},"Report":{"type":"object","properties":{"id":{"type":"string"},"channel":{"type":"string"},"target":{"type":"string"},"cadence":{"type":"string"},"next_run_at":{"type":"number"}},"required":["id","channel","target","cadence","next_run_at"]},"Alert":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string"},"channel":{"type":"string"},"target":{"type":"string"},"threshold":{"type":"object","properties":{"percent":{"type":"number"},"goal_id":{"type":"string"},"count":{"type":"number"}}},"last_fired_at":{"type":["number","null"]},"created_at":{"type":"number"}},"required":["id","type","channel","target","threshold","last_fired_at","created_at"]},"Integration":{"type":"object","properties":{"provider":{"type":"string"},"status":{"type":"string"},"last_sync_at":{"type":["number","null"]},"last_error":{"type":["string","null"]},"config":{"type":"object","additionalProperties":{}}},"required":["provider","status","last_sync_at","last_error","config"]},"Export":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"format":{"type":"string"},"from":{"type":"number"},"to":{"type":"number"},"url":{"type":"string"},"size_bytes":{"type":"number"},"created_at":{"type":"number"}},"required":["id","status","format","from","to","created_at"]},"AggregateResponse":{"type":"object","properties":{"current":{"type":"object","properties":{"visitors":{"type":"number"},"pageviews":{"type":"number"},"sessions":{"type":"number"},"bounce_rate":{"type":"number"},"avg_duration":{"type":"number"},"revenue":{"type":"number"},"net_revenue":{"type":"number"},"conversions":{"type":"number"},"conversion_rate":{"type":"number"},"rpv":{"type":"number"},"customers":{"type":"number"}},"required":["visitors","pageviews","sessions","bounce_rate","avg_duration","revenue","net_revenue","conversions","conversion_rate","rpv","customers"]},"previous":{"type":["object","null"],"properties":{"visitors":{"type":"number"},"pageviews":{"type":"number"},"sessions":{"type":"number"},"bounce_rate":{"type":"number"},"avg_duration":{"type":"number"},"revenue":{"type":"number"},"net_revenue":{"type":"number"},"conversions":{"type":"number"},"conversion_rate":{"type":"number"},"rpv":{"type":"number"},"customers":{"type":"number"}},"required":["visitors","pageviews","sessions","bounce_rate","avg_duration","revenue","net_revenue","conversions","conversion_rate","rpv","customers"]},"change":{"type":"object","additionalProperties":{"type":["number","null"]}},"meta":{"type":"object","properties":{"currency":{"type":"string"},"sampled":{"type":"boolean"},"from":{"type":"string"},"to":{"type":"string"},"source":{"type":"string","enum":["rollup","events"]}},"required":["currency","sampled","from","to","source"]}},"required":["current","previous","change","meta"]},"TimeseriesResponse":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"ts":{"type":"number"},"visitors":{"type":"number"},"pageviews":{"type":"number"},"sessions":{"type":"number"},"revenue":{"type":"number"},"conversions":{"type":"number"},"bounce_rate":{"type":"number"},"avg_duration":{"type":"number"}},"required":["ts","visitors","pageviews","sessions","revenue","conversions","bounce_rate","avg_duration"]}},"previous":{"type":["array","null"],"items":{"type":"object","properties":{"ts":{"type":"number"},"visitors":{"type":"number"},"pageviews":{"type":"number"},"sessions":{"type":"number"},"revenue":{"type":"number"},"conversions":{"type":"number"},"bounce_rate":{"type":"number"},"avg_duration":{"type":"number"}},"required":["ts","visitors","pageviews","sessions","revenue","conversions","bounce_rate","avg_duration"]}},"interval":{"type":"string","enum":["hour","day","week","month"]},"annotations":{"type":"array","items":{"type":"object","properties":{"ts":{"type":"number"},"label":{"type":"string"}},"required":["ts","label"]}}},"required":["results","previous","interval","annotations"]},"BreakdownResponse":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"label":{"type":"string"},"visitors":{"type":"number"},"pageviews":{"type":"number"},"sessions":{"type":"number"},"bounce_rate":{"type":"number"},"avg_duration":{"type":"number"},"revenue":{"type":"number"},"conversions":{"type":"number"},"conversion_rate":{"type":"number"},"rpv":{"type":"number"},"favicon":{"type":"string"}},"required":["value","visitors","revenue","conversion_rate","rpv"]}},"next_cursor":{"type":["string","null"]},"meta":{"type":"object","properties":{"currency":{"type":"string"},"sampled":{"type":"boolean"},"dimension":{"type":"string"}},"required":["currency","sampled","dimension"]}},"required":["results","next_cursor","meta"]},"RealtimeResponse":{"type":"object","properties":{"live":{"type":"number"},"feed":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string","enum":["pageview","event","payment","identify"]},"ts":{"type":"number"},"visitor_id":{"type":"string"},"pathname":{"type":["string","null"]},"name":{"type":["string","null"]},"country":{"type":["string","null"]},"city":{"type":["string","null"]},"lat":{"type":["number","null"]},"lon":{"type":["number","null"]},"channel":{"type":"string"},"referrer_domain":{"type":["string","null"]},"device":{"type":["string","null"]},"revenue_cents":{"type":["number","null"]},"currency":{"type":["string","null"]}},"required":["kind","ts","visitor_id","pathname","name","country","city","channel","referrer_domain","device","revenue_cents","currency"]}},"top_pages":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"visitors":{"type":"number"}},"required":["value","visitors"]}},"top_sources":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"visitors":{"type":"number"}},"required":["value","visitors"]}},"top_countries":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"visitors":{"type":"number"}},"required":["value","visitors"]}}},"required":["live","feed","top_pages","top_sources","top_countries"]},"RevenueSummaryResponse":{"type":"object","properties":{"revenue":{"type":"number"},"net_revenue":{"type":"number"},"new_revenue":{"type":"number"},"renewal_revenue":{"type":"number"},"refunds":{"type":"number"},"customers":{"type":"number"},"new_customers":{"type":"number"},"arpu":{"type":"number"},"mrr":{"type":"number"},"ltv":{"type":"number"},"churn_rate":{"type":"number"},"conversion_rate":{"type":"number"},"rpv":{"type":"number"},"currency":{"type":"string"},"previous":{"type":["object","null"],"properties":{"revenue":{"type":"number"},"net_revenue":{"type":"number"},"new_revenue":{"type":"number"},"renewal_revenue":{"type":"number"},"refunds":{"type":"number"},"customers":{"type":"number"},"new_customers":{"type":"number"},"arpu":{"type":"number"},"mrr":{"type":"number"},"ltv":{"type":"number"},"churn_rate":{"type":"number"},"conversion_rate":{"type":"number"},"rpv":{"type":"number"},"currency":{"type":"string"}},"required":["revenue","net_revenue","new_revenue","renewal_revenue","refunds","customers","new_customers","arpu","mrr","ltv","churn_rate","conversion_rate","rpv","currency"]}},"required":["revenue","net_revenue","new_revenue","renewal_revenue","refunds","customers","new_customers","arpu","mrr","ltv","churn_rate","conversion_rate","rpv","currency","previous"]},"PaymentWithTouches":{"type":"object","properties":{"id":{"type":"string"},"provider":{"type":"string","enum":["stripe","lemonsqueezy","paddle","polar","shopify","api"]},"provider_payment_id":{"type":"string"},"provider_customer_id":{"type":["string","null"],"default":null},"visitor_id":{"type":["string","null"],"default":null},"user_id":{"type":["string","null"],"default":null},"customer_email_hash":{"type":["string","null"],"default":null},"amount_cents":{"type":"integer"},"currency":{"type":"string","minLength":3,"maxLength":3},"amount_site_cents":{"type":"integer"},"type":{"type":"string","enum":["new","renewal","refund","one_time"]},"ts":{"type":"integer"},"subscription_id":{"type":["string","null"],"default":null},"product":{"type":["string","null"],"default":null},"first_touch_json":{"type":["string","null"],"default":null},"last_touch_json":{"type":["string","null"],"default":null},"touches_json":{"type":["string","null"],"default":null},"first_touch":{"type":["object","null"],"properties":{"ts":{"type":"number"},"session_id":{"type":"string"},"channel":{"type":"string"},"referrer_domain":{"type":["string","null"]},"utm_source":{"type":["string","null"]},"utm_medium":{"type":["string","null"]},"utm_campaign":{"type":["string","null"]},"entry_path":{"type":["string","null"]},"country":{"type":["string","null"]},"device":{"type":["string","null"]}},"required":["ts","session_id","channel","referrer_domain","utm_source","utm_medium","utm_campaign","entry_path","country","device"]},"last_touch":{"type":["object","null"],"properties":{"ts":{"type":"number"},"session_id":{"type":"string"},"channel":{"type":"string"},"referrer_domain":{"type":["string","null"]},"utm_source":{"type":["string","null"]},"utm_medium":{"type":["string","null"]},"utm_campaign":{"type":["string","null"]},"entry_path":{"type":["string","null"]},"country":{"type":["string","null"]},"device":{"type":["string","null"]}},"required":["ts","session_id","channel","referrer_domain","utm_source","utm_medium","utm_campaign","entry_path","country","device"]}},"required":["id","provider","provider_payment_id","amount_cents","currency","amount_site_cents","type","ts","first_touch","last_touch"]},"Customer":{"type":"object","properties":{"visitor_id":{"type":["string","null"]},"user_id":{"type":["string","null"]},"email_hash":{"type":["string","null"]},"first_ts":{"type":"number"},"last_ts":{"type":"number"},"revenue_cents":{"type":"number"},"payments":{"type":"number"},"last_channel":{"type":["string","null"]},"last_source":{"type":["string","null"]}},"required":["visitor_id","user_id","email_hash","first_ts","last_ts","revenue_cents","payments","last_channel","last_source"]},"ShareInfo":{"type":"object","properties":{"site":{"type":"object","properties":{"name":{"type":"string"},"domain":{"type":"string"},"timezone":{"type":"string"},"currency":{"type":"string"}},"required":["name","domain","timezone","currency"]},"hide_revenue":{"type":"boolean"},"has_password":{"type":"boolean"},"unlocked":{"type":"boolean"},"white_label":{"type":["object","null"],"properties":{"logo_url":{"type":["string","null"]},"accent":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["logo_url","accent","name"]},"badge":{"type":"boolean"}},"required":["site","hide_revenue","has_password","unlocked","white_label","badge"]}},"parameters":{}},"paths":{"/health":{"get":{"tags":["System"],"summary":"Health check","description":"Liveness probe; also verifies the control-plane database answers.","responses":{"200":{"description":"Healthy","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"env":{"type":"string"},"db":{"type":"boolean"},"ts":{"type":"number"}},"required":["ok","env","db","ts"]},"example":{"ok":true,"env":"production","db":true,"ts":1762300800000}}}},"503":{"description":"Degraded"}}}},"/app/auth/signup":{"post":{"tags":["Auth"],"summary":"Sign up with email and password","description":"Creates the user, an organisation (slug derived from the name), a \"Default\" workspace, the owner membership and a 14-day Growth trial. Sets the `rf_session` and `rf_csrf` cookies.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"},"password":{"type":"string","minLength":10,"maxLength":256},"name":{"type":"string","minLength":1,"maxLength":100},"turnstile":{"type":"string"}},"required":["email","password","name"]},"example":{"email":"ada@example.com","password":"correct horse battery","name":"Ada"}}}},"responses":{"201":{"description":"Account created","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/User"},"org":{"$ref":"#/components/schemas/OrgSummary"},"workspace":{"$ref":"#/components/schemas/Workspace"}},"required":["user","org","workspace"]},"example":{"user":{"id":"usr_01jgq0b1h3xk2m8v9n4p5q6r7s","email":"ada@example.com","name":"Ada","avatar_url":null,"last_org_id":null,"last_site_id":null},"org":{"id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Ada's workspace","slug":"adas-workspace","plan":"growth","role":"owner","trial_ends_at":1767225600000},"workspace":{"id":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s","org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Default","slug":"default","is_client":false,"created_at":1762300800000,"sites_count":0}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"conflict","message":"Conflict","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/auth/login":{"post":{"tags":["Auth"],"summary":"Log in with email and password","description":"Verifies the password and sets the session cookies. Returns 401 for unknown emails and wrong passwords alike.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"},"password":{"type":"string","minLength":10,"maxLength":256},"turnstile":{"type":"string"}},"required":["email","password"]},"example":{"email":"ada@example.com","password":"correct horse battery"}}}},"responses":{"200":{"description":"Logged in","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/User"}},"required":["user"]},"example":{"user":{"id":"usr_01jgq0b1h3xk2m8v9n4p5q6r7s","email":"ada@example.com","name":"Ada","avatar_url":null,"last_org_id":null,"last_site_id":null}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/auth/logout":{"post":{"tags":["Auth"],"summary":"Log out","description":"Deletes the current session and clears the cookies.","security":[{"cookie":[]}],"responses":{"204":{"description":"Logged out"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/auth/magic":{"post":{"tags":["Auth"],"summary":"Request a magic sign-in link","description":"Always returns 200 so email existence is not revealed. Sends the link through Resend; the token expires after 15 minutes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"},"turnstile":{"type":"string"}},"required":["email"]},"example":{"email":"ada@example.com"}}}},"responses":{"200":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]}},"required":["ok"]},"example":{"ok":true}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/auth/magic/verify":{"get":{"tags":["Auth"],"summary":"Verify a magic link","description":"Consumes the token, creates the user (and an organisation) when new, sets the session cookies and redirects to the app.","parameters":[{"schema":{"type":"string","minLength":16,"example":"k3J9..."},"required":true,"name":"token","in":"query"}],"responses":{"302":{"description":"Redirect to `${APP_URL}/app` or `/login?error=invalid_token`"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/auth/oauth/{provider}":{"get":{"tags":["Auth"],"summary":"Start OAuth sign-in","description":"Redirects to Google or GitHub. The `state` token is stored in `auth_tokens` (kind `oauth_state`) and consumed once by the callback.","parameters":[{"schema":{"type":"string","enum":["google","github"],"example":"google"},"required":true,"name":"provider","in":"path"},{"schema":{"type":"string","maxLength":256},"required":false,"name":"redirect","in":"query"}],"responses":{"302":{"description":"Redirect to the provider"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/auth/oauth/{provider}/callback":{"get":{"tags":["Auth"],"summary":"OAuth callback","description":"Exchanges the code, links or creates the user (matching on a verified email), sets the session cookies and redirects to the app.","parameters":[{"schema":{"type":"string","enum":["google","github"],"example":"google"},"required":true,"name":"provider","in":"path"},{"schema":{"type":"string"},"required":false,"name":"code","in":"query"},{"schema":{"type":"string"},"required":false,"name":"state","in":"query"},{"schema":{"type":"string"},"required":false,"name":"error","in":"query"}],"responses":{"302":{"description":"Redirect to `${APP_URL}/app` or `/login?error=oauth_failed`"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/auth/forgot":{"post":{"tags":["Auth"],"summary":"Request a password reset","description":"Always returns 200. Emails a reset link valid for 30 minutes when the account exists.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"},"turnstile":{"type":"string"}},"required":["email"]},"example":{"email":"ada@example.com"}}}},"responses":{"200":{"description":"Accepted","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]}},"required":["ok"]},"example":{"ok":true}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/auth/reset":{"post":{"tags":["Auth"],"summary":"Reset the password","description":"Consumes the reset token, stores the new password hash and revokes every existing session of the user.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","minLength":16},"password":{"type":"string","minLength":10,"maxLength":256}},"required":["token","password"]},"example":{"token":"k3J9...","password":"new strong passphrase"}}}},"responses":{"200":{"description":"Password updated","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]}},"required":["ok"]},"example":{"ok":true}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/auth/me":{"get":{"tags":["Auth"],"summary":"Current user","description":"The signed-in user, their organisations with role, and the CSRF token to send as `X-CSRF-Token` on mutations.","security":[{"cookie":[]}],"responses":{"200":{"description":"Current user","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/User"},"orgs":{"type":"array","items":{"$ref":"#/components/schemas/OrgSummary"}},"csrf":{"type":"string"}},"required":["user","orgs","csrf"]},"example":{"user":{"id":"usr_01jgq0b1h3xk2m8v9n4p5q6r7s","email":"ada@example.com","name":"Ada","avatar_url":null,"last_org_id":null,"last_site_id":null},"orgs":[{"id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Ada's workspace","slug":"adas-workspace","plan":"growth","role":"owner","trial_ends_at":1767225600000}],"csrf":"c5f1..."}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/auth/me/last":{"post":{"tags":["Auth"],"summary":"Remember the last org / site","description":"Stores the last visited org and site so `/app` can redirect straight to the dashboard.","security":[{"cookie":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string"},"site_id":{"type":"string"}}},"example":{"org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"}}}},"responses":{"204":{"description":"Saved"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs":{"get":{"tags":["Orgs"],"security":[{"cookie":[]}],"summary":"List organisations","description":"Organisations the signed-in user belongs to, with their role.","responses":{"200":{"description":"Organisations","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"plan":{"type":"string"},"role":{"type":"string"}},"required":["id","name","slug","plan","role"]}}},"required":["results"]},"example":{"results":[{"id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Acme","slug":"acme","plan":"growth","role":"owner"}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"post":{"tags":["Orgs"],"security":[{"cookie":[]}],"summary":"Create an organisation","description":"Creates an organisation (free plan, no trial) with a Default workspace; the caller becomes owner.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100}},"required":["name"]},"example":{"name":"Acme"}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"org":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"plan":{"type":"string"},"role":{"type":"string"},"trial_ends_at":{"type":["number","null"]}},"required":["id","name","slug","plan","role","trial_ends_at"]},"workspace":{"type":"object","properties":{"id":{"type":"string"},"org_id":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"is_client":{"type":"boolean"},"created_at":{"type":"number"},"sites_count":{"type":"number"}},"required":["id","org_id","name","slug","is_client","created_at","sites_count"]}},"required":["org","workspace"]},"example":{"org":{"id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Acme","slug":"acme","plan":"growth","role":"owner","trial_ends_at":null},"workspace":{"id":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s","org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Default","slug":"default","is_client":false,"created_at":1762300800000,"sites_count":0}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}":{"get":{"tags":["Orgs"],"security":[{"cookie":[]}],"summary":"Get an organisation","description":"Plan, trial, white-label settings, this month's usage against quota, plan limits (unlimited = null) and the caller's role.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"responses":{"200":{"description":"Organisation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgDetail"},"example":{"id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Acme","slug":"acme","plan":"growth","role":"owner","plan_interval":"month","trial_ends_at":null,"white_label":{"logo_url":null,"accent":null,"name":null},"usage":{"events":12000,"quota":100000,"month":"2026-11","warned":false},"limits":{"id":"growth","sites":30,"seats":null}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"patch":{"tags":["Orgs"],"security":[{"cookie":[]}],"summary":"Update an organisation","description":"Renames the organisation or sets white-label branding (Agency plan). Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"white_label":{"type":"object","properties":{"logo_url":{"type":["string","null"],"format":"uri","default":null},"accent":{"type":["string","null"],"pattern":"^#[0-9a-fA-F]{6}$","default":null},"name":{"type":["string","null"],"maxLength":100,"default":null}}}}},"example":{"name":"Acme Inc","white_label":{"logo_url":"https://acme.com/logo.svg","accent":"#4f46e5","name":"Acme Analytics"}}}}},"responses":{"200":{"description":"Updated organisation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgDetail"},"example":{"id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Acme","slug":"acme","plan":"growth","role":"owner","plan_interval":"month","trial_ends_at":null,"white_label":{"logo_url":null,"accent":null,"name":null},"usage":{"events":12000,"quota":100000,"month":"2026-11","warned":false},"limits":{"id":"growth","sites":30,"seats":null}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"delete":{"tags":["Orgs"],"security":[{"cookie":[]}],"summary":"Delete an organisation","description":"Owner only. Soft-deletes the organisation and its sites and stops tracking immediately; all site databases and archives are hard-deleted after 30 days by the `dsr-delete` workflow.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"responses":{"202":{"description":"Deletion scheduled","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"deleted_at":{"type":"number"},"hard_delete_after":{"type":"number"}},"required":["id","deleted_at","hard_delete_after"]},"example":{"id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","deleted_at":1762300800000,"hard_delete_after":1764892800000}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}/audit":{"get":{"tags":["Orgs"],"security":[{"cookie":[]}],"summary":"Audit log","description":"Every mutation in the organisation, newest first. Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Audit entries","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"user":{"type":["object","null"],"properties":{"id":{"type":"string"},"email":{"type":["string","null"]},"name":{"type":["string","null"]}},"required":["id","email","name"]},"action":{"type":"string"},"target":{"type":["string","null"]},"meta":{"type":["object","null"],"additionalProperties":{}},"ts":{"type":"number"}},"required":["id","user","action","target","meta","ts"]}},"next_cursor":{"type":["string","null"]}},"required":["results","next_cursor"]},"example":{"results":[{"id":"aud_01jgq0b1h3xk2m8v9n4p5q6r7s","user":{"id":"usr_01…","email":"ada@example.com","name":"Ada"},"action":"site.create","target":"site_01…","meta":{"domain":"example.com"},"ts":1762300800000}],"next_cursor":null}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}/workspaces":{"get":{"tags":["Workspaces"],"security":[{"cookie":[]}],"summary":"List workspaces","description":"Workspaces visible to the caller, with site counts.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"responses":{"200":{"description":"Workspaces","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Workspace"}}},"required":["results"]},"example":{"results":[{"id":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s","org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Client: Globex","slug":"client-globex","is_client":true,"created_at":1762300800000,"sites_count":2}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"post":{"tags":["Workspaces"],"security":[{"cookie":[]}],"summary":"Create a workspace","description":"Creates a workspace. Client workspaces (`is_client`) need the Agency plan. Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"is_client":{"type":"boolean"}},"required":["name"]},"example":{"name":"Client: Globex","is_client":true}}}},"responses":{"201":{"description":"Created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"},"example":{"id":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s","org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Client: Globex","slug":"client-globex","is_client":true,"created_at":1762300800000,"sites_count":2}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/workspaces/{wsId}":{"get":{"tags":["Workspaces"],"security":[{"cookie":[]}],"summary":"Get a workspace","description":"One workspace with its site count.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"wsId","in":"path"}],"responses":{"200":{"description":"Workspace","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"},"example":{"id":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s","org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Client: Globex","slug":"client-globex","is_client":true,"created_at":1762300800000,"sites_count":2}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"patch":{"tags":["Workspaces"],"security":[{"cookie":[]}],"summary":"Rename a workspace","description":"Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"wsId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100}}},"example":{"name":"Marketing"}}}},"responses":{"200":{"description":"Updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Workspace"},"example":{"id":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s","org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Client: Globex","slug":"client-globex","is_client":true,"created_at":1762300800000,"sites_count":2}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"delete":{"tags":["Workspaces"],"security":[{"cookie":[]}],"summary":"Delete a workspace","description":"Soft-deletes an empty workspace (409 while it still has sites, or when it is the last one). Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"wsId","in":"path"}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"conflict","message":"Conflict","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}/members":{"get":{"tags":["Members"],"security":[{"cookie":[]}],"summary":"List members and invites","description":"Members with their highest role, workspace/site restrictions, and pending invites.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"responses":{"200":{"description":"Members","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Member"}},"invites":{"type":"array","items":{"$ref":"#/components/schemas/Invite"}}},"required":["results","invites"]},"example":{"results":[{"user_id":"usr_01jgq0b1h3xk2m8v9n4p5q6r7s","email":"ada@example.com","name":"Ada","avatar_url":null,"role":"owner","workspace_id":null,"site_ids":null,"created_at":1762300800000}],"invites":[{"id":"inv_01jgq0b1h3xk2m8v9n4p5q6r7s","email":"bob@example.com","role":"member","workspace_id":null,"expires_at":1762905600000}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}/invites":{"post":{"tags":["Members"],"security":[{"cookie":[]}],"summary":"Invite a member","description":"Emails an invitation link (`${APP_URL}/invite/{token}`) valid for 7 days. Enforces plan seats. Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","maxLength":254,"format":"email"},"role":{"type":"string","enum":["admin","member","viewer","client"]},"workspace_id":{"type":"string"},"site_ids":{"type":"array","items":{"type":"string"}}},"required":["email","role"]},"example":{"email":"bob@example.com","role":"member"}}}},"responses":{"201":{"description":"Invited","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]},"example":{"id":"inv_01jgq0b1h3xk2m8v9n4p5q6r7s"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}/invites/{id}":{"delete":{"tags":["Members"],"security":[{"cookie":[]}],"summary":"Revoke an invite","description":"Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"inv_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Revoked"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}/members/{userId}":{"patch":{"tags":["Members"],"security":[{"cookie":[]}],"summary":"Change a member role","description":"Requires `admin`+; only owners can grant or remove the owner role, and the last owner cannot be demoted.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"usr_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"userId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"string","enum":["owner","admin","member","viewer","client"]}},"required":["role"]},"example":{"role":"admin"}}}},"responses":{"200":{"description":"Updated member","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Member"},"example":{"user_id":"usr_01jgq0b1h3xk2m8v9n4p5q6r7s","email":"ada@example.com","name":"Ada","avatar_url":null,"role":"admin","workspace_id":null,"site_ids":null,"created_at":1762300800000}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"conflict","message":"Conflict","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"delete":{"tags":["Members"],"security":[{"cookie":[]}],"summary":"Remove a member","description":"Requires `admin`+ (members may remove themselves). The last owner cannot be removed.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"usr_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"userId","in":"path"}],"responses":{"204":{"description":"Removed"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"409":{"description":"Conflict","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"conflict","message":"Conflict","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/invites/{token}":{"get":{"tags":["Members"],"summary":"Preview an invite","description":"Public: what the invite link grants, shown before sign-in.","parameters":[{"schema":{"type":"string","minLength":16,"maxLength":128,"example":"k3J9xQ2m…"},"required":true,"name":"token","in":"path"}],"responses":{"200":{"description":"Invite","content":{"application/json":{"schema":{"type":"object","properties":{"org_name":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"},"workspace_name":{"type":["string","null"]}},"required":["org_name","email","role","workspace_name"]},"example":{"org_name":"Acme","email":"bob@example.com","role":"member","workspace_name":null}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/invites/{token}/accept":{"post":{"tags":["Members"],"security":[{"cookie":[]}],"summary":"Accept an invite","description":"Adds the signed-in user to the organisation. The user's email must match the invited email.","parameters":[{"schema":{"type":"string","minLength":16,"maxLength":128,"example":"k3J9xQ2m…"},"required":true,"name":"token","in":"path"}],"responses":{"200":{"description":"Joined","content":{"application/json":{"schema":{"type":"object","properties":{"org_id":{"type":"string"}},"required":["org_id"]},"example":{"org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}/api-keys":{"get":{"tags":["API keys"],"security":[{"cookie":[]}],"summary":"List API keys","description":"Active keys (prefix only; the secret is shown once at creation). Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"responses":{"200":{"description":"Keys","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}},"required":["results"]},"example":{"results":[{"id":"key_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Server","prefix":"rf_live_8f2a","scopes":["stats:read","events:write"],"site_id":null,"last_used_at":null,"created_at":1762300800000}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"post":{"tags":["API keys"],"security":[{"cookie":[]}],"summary":"Create an API key","description":"Creates an `rf_live_` (or `rf_test_`) key with scopes, optionally restricted to one site. The key is returned once; only its SHA-256 is stored. Starter plan and above. Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"scopes":{"type":"array","items":{"type":"string","enum":["stats:read","events:write","sites:write","payments:write"]},"minItems":1},"site_id":{"type":"string"},"test":{"type":"boolean","default":false}},"required":["name","scopes"]},"example":{"name":"Server","scopes":["stats:read","events:write"]}}}},"responses":{"201":{"description":"Created (key shown once)","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"}},"required":["id","key"]},"example":{"id":"key_01jgq0b1h3xk2m8v9n4p5q6r7s","key":"rf_live_8f2aQ…"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}/api-keys/{id}":{"delete":{"tags":["API keys"],"security":[{"cookie":[]}],"summary":"Revoke an API key","description":"Revokes the key immediately. Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"key_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Revoked"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}/billing":{"get":{"tags":["Billing"],"security":[{"cookie":[]}],"summary":"Billing overview","description":"Plan and status (trialing, active, past_due, canceling, expired), tier, this period's event usage, Polar orders, and the plan and price tables for the pricing UI. Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"responses":{"200":{"description":"Billing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Billing"},"example":{"plan":"growth","status":"trialing","plan_interval":null,"tier":null,"trial_ends_at":1763510400000,"current_period_end":null,"has_billing_customer":false,"usage":{"events":1200,"quota":100000,"period_start":1761955200000,"period_end":1764547199999,"percent":0.012,"grace_until":null},"invoices":[],"plans":{"growth":{"id":"growth","sites":30,"seats":30}},"tiers":[{"id":"10k","label":"10k","events":10000,"starter":9,"growth":19}],"trial_days":14,"yearly_months_charged":10}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}/billing/checkout":{"post":{"tags":["Billing"],"security":[{"cookie":[]}],"summary":"Start a Polar checkout","description":"Creates a Polar checkout session for the plan, event tier and interval (or, when the org already has a live subscription, switches that subscription to the new product and returns the billing page URL). The product is found by its `realific_plan`, `realific_tier` and `realific_interval` metadata. The org id is the Polar customer `external_id`, so the `polar-billing` webhook can apply the plan. Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"plan":{"type":"string","enum":["starter","growth"]},"tier":{"type":"string","enum":["10k","100k","200k","500k","1m","2m","5m","10m","10m_plus"],"default":"10k"},"interval":{"type":"string","enum":["month","year"],"default":"month"}},"required":["plan"]},"example":{"plan":"growth","tier":"100k","interval":"year"}}}},"responses":{"200":{"description":"Checkout URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]},"example":{"url":"https://buy.polar.sh/polar_c_…"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/orgs/{orgId}/billing/portal":{"post":{"tags":["Billing"],"security":[{"cookie":[]}],"summary":"Open the Polar customer portal","description":"Creates a Polar customer session for the org (by `external_customer_id`) and returns the portal URL, where the customer manages their payment method, invoices, plan and cancellation. Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"orgId","in":"path"}],"responses":{"200":{"description":"Portal URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]},"example":{"url":"https://polar.sh/realific/portal?customer_session_token=…"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites":{"get":{"tags":["Sites"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"List sites","description":"Sites the caller may read, optionally narrowed to one organisation and/or workspace. Client-role members only see their assigned sites.","parameters":[{"schema":{"type":"string","example":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":false,"name":"org_id","in":"query"},{"schema":{"type":"string","example":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":false,"name":"workspace_id","in":"query"}],"responses":{"200":{"description":"Sites","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Site"}}},"required":["results"]},"example":{"results":[{"id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","workspace_id":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s","org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","domain":"example.com","name":"Example","timezone":"Europe/Berlin","currency":"EUR","public_key":"pk_Xb3k9QmT2vLr","cookieless":false,"settings":{"track_outbound":true,"track_downloads":true,"hash_routing":false,"allowed_domains":[],"exclude_paths":[],"exclude_ips":[],"exclude_countries":[],"respect_dnt":false,"custom_domain":null},"created_at":1762300800000}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"post":{"tags":["Sites"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Create a site","description":"Creates a site in a workspace, provisions its analytics database (a pooled D1 binding, or a dedicated D1 in REST mode), runs site migrations, and writes the KV entry `site:{public_key}` read by the ingest Worker. Enforces the plan site limit. Requires `member`+ or the `sites:write` scope.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"workspace_id":{"type":"string"},"domain":{"type":"string","minLength":3,"maxLength":253,"pattern":"^(?!-)(?:[a-z0-9-]{1,63}\\.)+[a-z]{2,63}$"},"name":{"type":"string","minLength":1,"maxLength":100},"timezone":{"type":"string","minLength":1,"maxLength":64,"default":"UTC"},"currency":{"type":"string","minLength":3,"maxLength":3,"default":"USD"},"cookieless":{"type":"boolean","default":false}},"required":["workspace_id","domain"]},"example":{"workspace_id":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s","domain":"example.com","name":"Example","timezone":"Europe/Berlin","currency":"EUR"}}}},"responses":{"201":{"description":"Site created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"},"example":{"id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","workspace_id":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s","org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","domain":"example.com","name":"Example","timezone":"Europe/Berlin","currency":"EUR","public_key":"pk_Xb3k9QmT2vLr","cookieless":false,"settings":{"track_outbound":true,"track_downloads":true,"hash_routing":false,"allowed_domains":[],"exclude_paths":[],"exclude_ips":[],"exclude_countries":[],"respect_dnt":false,"custom_domain":null},"created_at":1762300800000}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}":{"get":{"tags":["Sites"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Get a site","description":"Site settings plus install state and the tracking snippet. Returns 404 for sites outside the caller's organisations.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Site","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteDetail"},"example":{"id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","workspace_id":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s","org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","domain":"example.com","name":"Example","timezone":"Europe/Berlin","currency":"EUR","public_key":"pk_Xb3k9QmT2vLr","cookieless":false,"settings":{"track_outbound":true,"track_downloads":true,"hash_routing":false,"allowed_domains":[],"exclude_paths":[],"exclude_ips":[],"exclude_countries":[],"respect_dnt":false,"custom_domain":null},"created_at":1762300800000,"first_event_at":1762300900000,"installed":true,"snippet":"<script defer data-site=\"pk_Xb3k9QmT2vLr\" data-domain=\"example.com\" src=\"https://realific.app/r.js\"></script>\n<script>window.realific=window.realific||function(){(realific.q=realific.q||[]).push(arguments)};</script>"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"patch":{"tags":["Sites"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Update a site","description":"Updates name, timezone, currency, cookieless mode and tracking settings, then refreshes the KV entry used by the ingest Worker.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"timezone":{"type":"string","minLength":1,"maxLength":64},"currency":{"type":"string","minLength":3,"maxLength":3},"cookieless":{"type":"boolean"},"settings":{"type":"object","properties":{"track_outbound":{"type":"boolean","default":true},"track_downloads":{"type":"boolean","default":true},"hash_routing":{"type":"boolean","default":false},"allowed_domains":{"type":"array","items":{"type":"string","minLength":3,"maxLength":253,"pattern":"^(?!-)(?:[a-z0-9-]{1,63}\\.)+[a-z]{2,63}$"},"maxItems":20,"default":[]},"exclude_paths":{"type":"array","items":{"type":"string","maxLength":256},"maxItems":50,"default":[]},"exclude_ips":{"type":"array","items":{"type":"string","maxLength":64},"maxItems":50,"default":[]},"exclude_countries":{"type":"array","items":{"type":"string","minLength":2,"maxLength":2},"maxItems":50,"default":[]},"respect_dnt":{"type":"boolean","default":false},"custom_domain":{"type":["string","null"],"maxLength":253,"default":null}}}}},"example":{"name":"Example shop","settings":{"exclude_paths":["/admin/*"],"respect_dnt":true}}}}},"responses":{"200":{"description":"Updated site","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Site"},"example":{"id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","workspace_id":"ws_01jgq0b1h3xk2m8v9n4p5q6r7s","org_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s","domain":"example.com","name":"Example","timezone":"Europe/Berlin","currency":"EUR","public_key":"pk_Xb3k9QmT2vLr","cookieless":false,"settings":{"track_outbound":true,"track_downloads":true,"hash_routing":false,"allowed_domains":[],"exclude_paths":[],"exclude_ips":[],"exclude_countries":[],"respect_dnt":false,"custom_domain":null},"created_at":1762300800000}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"delete":{"tags":["Sites"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Delete a site","description":"Soft-deletes the site and removes its KV entries so tracking stops immediately. The analytics database is dropped by a workflow after 30 days. Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"202":{"description":"Deletion scheduled","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"deleted_at":{"type":"number"}},"required":["id","deleted_at"]},"example":{"id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","deleted_at":1762300800000}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/install-status":{"get":{"tags":["Sites"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Install status","description":"Polled by onboarding: whether the first event has arrived and how many visitors are live right now.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Install status","content":{"application/json":{"schema":{"type":"object","properties":{"installed":{"type":"boolean"},"first_event_at":{"type":["number","null"]},"live_now":{"type":"number"}},"required":["installed","first_event_at","live_now"]},"example":{"installed":true,"first_event_at":1762300900000,"live_now":3}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/verify":{"post":{"tags":["Sites"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Verify the snippet","description":"Fetches a page of the site server-side and checks whether it contains the site public key. Only URLs on the site domain (or its allowed domains) are fetched.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri"}}},"example":{"url":"https://example.com/"}}}},"responses":{"200":{"description":"Verification result","content":{"application/json":{"schema":{"type":"object","properties":{"script_found":{"type":"boolean"},"fetched_url":{"type":"string"}},"required":["script_found","fetched_url"]},"example":{"script_found":true,"fetched_url":"https://example.com/"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/event-names":{"get":{"tags":["Sites"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Custom event names","description":"Distinct custom event names with counts in the range (default last 30 days). Used by the goal editor.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$","example":"2026-10-01"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$","example":"2026-10-31"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"Event names","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"count":{"type":"number"}},"required":["name","count"]}}},"required":["results"]},"example":{"results":[{"name":"signup","count":120}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/goals":{"get":{"tags":["Goals"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"List goals","description":"Conversion goals defined for the site (pageview path globs, custom events, or revenue).","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Goals","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Goal"}}},"required":["results"]},"example":{"results":[{"id":"goal_01jgq0b1h3xk2m8v9n4p5q6r7s","site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Signup","type":"event","match":{"type":"event","name":"signup"},"created_at":1762300800000}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"post":{"tags":["Goals"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Create a goal","description":"Creates a goal. At most 50 goals per site.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"match":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["pageview"]},"path":{"type":"string","minLength":1,"maxLength":256}},"required":["type","path"]},{"type":"object","properties":{"type":{"type":"string","enum":["event"]},"name":{"type":"string","minLength":1,"maxLength":64},"prop_key":{"type":"string","maxLength":64},"prop_value":{"type":"string","maxLength":255}},"required":["type","name"]},{"type":"object","properties":{"type":{"type":"string","enum":["revenue"]}},"required":["type"]}]}},"required":["name","match"]},"example":{"name":"Signup","match":{"type":"event","name":"signup"}}}}},"responses":{"201":{"description":"Goal created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Goal"},"example":{"id":"goal_01jgq0b1h3xk2m8v9n4p5q6r7s","site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Signup","type":"event","match":{"type":"event","name":"signup"},"created_at":1762300800000}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/goals/{gid}":{"patch":{"tags":["Goals"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Update a goal","description":"Renames a goal or changes its match rule.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"goal_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"gid","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"match":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["pageview"]},"path":{"type":"string","minLength":1,"maxLength":256}},"required":["type","path"]},{"type":"object","properties":{"type":{"type":"string","enum":["event"]},"name":{"type":"string","minLength":1,"maxLength":64},"prop_key":{"type":"string","maxLength":64},"prop_value":{"type":"string","maxLength":255}},"required":["type","name"]},{"type":"object","properties":{"type":{"type":"string","enum":["revenue"]}},"required":["type"]}]}}},"example":{"name":"Trial signup"}}}},"responses":{"200":{"description":"Updated goal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Goal"},"example":{"id":"goal_01jgq0b1h3xk2m8v9n4p5q6r7s","site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Signup","type":"event","match":{"type":"event","name":"signup"},"created_at":1762300800000}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"delete":{"tags":["Goals"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Delete a goal","description":"Deletes the goal. Historical events are unaffected.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"goal_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"gid","in":"path"}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/funnels":{"get":{"tags":["Funnels"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"List funnels","description":"Funnels defined for the site.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Funnels","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Funnel"}}},"required":["results"]},"example":{"results":[{"id":"fun_01jgq0b1h3xk2m8v9n4p5q6r7s","site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Signup funnel","steps":[{"type":"pageview","path":"/pricing"},{"type":"event","name":"signup"}],"window_sec":604800}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"post":{"tags":["Funnels"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Create a funnel","description":"2 to 8 ordered steps (pageview, event or goal) completed within `window_sec`. Growth plan and above.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"steps":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["pageview"]},"path":{"type":"string","minLength":1,"maxLength":256},"label":{"type":"string","maxLength":64}},"required":["type","path"]},{"type":"object","properties":{"type":{"type":"string","enum":["event"]},"name":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","maxLength":64}},"required":["type","name"]},{"type":"object","properties":{"type":{"type":"string","enum":["goal"]},"goal_id":{"type":"string"},"label":{"type":"string","maxLength":64}},"required":["type","goal_id"]}]},"minItems":2,"maxItems":8},"window_sec":{"type":"integer","minimum":3600,"maximum":2592000,"default":604800}},"required":["name","steps"]},"example":{"name":"Signup funnel","steps":[{"type":"pageview","path":"/pricing"},{"type":"event","name":"signup"}],"window_sec":604800}}}},"responses":{"201":{"description":"Funnel created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Funnel"},"example":{"id":"fun_01jgq0b1h3xk2m8v9n4p5q6r7s","site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Signup funnel","steps":[{"type":"pageview","path":"/pricing"},{"type":"event","name":"signup"}],"window_sec":604800}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/funnels/{fid}":{"patch":{"tags":["Funnels"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Update a funnel","description":"Changes the name, steps or window of a funnel.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"fun_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"fid","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"steps":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["pageview"]},"path":{"type":"string","minLength":1,"maxLength":256},"label":{"type":"string","maxLength":64}},"required":["type","path"]},{"type":"object","properties":{"type":{"type":"string","enum":["event"]},"name":{"type":"string","minLength":1,"maxLength":64},"label":{"type":"string","maxLength":64}},"required":["type","name"]},{"type":"object","properties":{"type":{"type":"string","enum":["goal"]},"goal_id":{"type":"string"},"label":{"type":"string","maxLength":64}},"required":["type","goal_id"]}]},"minItems":2,"maxItems":8},"window_sec":{"type":"integer","minimum":3600,"maximum":2592000,"default":604800}}},"example":{"name":"Checkout funnel"}}}},"responses":{"200":{"description":"Updated funnel","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Funnel"},"example":{"id":"fun_01jgq0b1h3xk2m8v9n4p5q6r7s","site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Signup funnel","steps":[{"type":"pageview","path":"/pricing"},{"type":"event","name":"signup"}],"window_sec":604800}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"delete":{"tags":["Funnels"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Delete a funnel","description":"Deletes the funnel definition.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"fun_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"fid","in":"path"}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/funnels/{fid}/results":{"get":{"tags":["Funnels"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Funnel results","description":"Visitors entering each step, step conversion, drop-off and median time between steps.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"fun_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"fid","in":"path"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"to","in":"query"},{"schema":{"type":"string","maxLength":64,"default":"UTC"},"required":false,"name":"tz","in":"query"},{"schema":{"type":"string"},"required":false,"name":"filters","in":"query"}],"responses":{"200":{"description":"Funnel results","content":{"application/json":{"schema":{"type":"object","properties":{"entered":{"type":"number"},"steps":{"type":"array","items":{"type":"object","properties":{"index":{"type":"number"},"label":{"type":"string"},"count":{"type":"number"},"conversion":{"type":"number"},"drop_off":{"type":"number"},"median_seconds":{"type":["number","null"]}},"required":["index","label","count","conversion","drop_off","median_seconds"]}},"breakdown":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"value":{"type":"string"},"entered":{"type":"number"},"completed":{"type":"number"}},"required":["value","entered","completed"]}}}},"required":["entered","steps"]},"example":{"entered":1000,"steps":[{"index":0,"label":"/pricing","count":1000,"conversion":1,"drop_off":0,"median_seconds":null},{"index":1,"label":"signup","count":120,"conversion":0.12,"drop_off":0.88,"median_seconds":95}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/annotations":{"get":{"tags":["Annotations"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"List annotations","description":"Chart annotations, optionally limited to a date range (interpreted in the site timezone).","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$","example":"2026-10-01"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$","example":"2026-10-31"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"Annotations","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Annotation"}}},"required":["results"]},"example":{"results":[{"id":"ann_01jgq0b1h3xk2m8v9n4p5q6r7s","ts":1762300800000,"label":"Launched on Product Hunt","source":"manual"}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"post":{"tags":["Annotations"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Create an annotation","description":"Adds a labelled marker shown on timeseries charts.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"ts":{"type":"integer"},"label":{"type":"string","minLength":1,"maxLength":200},"source":{"type":"string","maxLength":32,"default":"manual"}},"required":["ts","label"]},"example":{"ts":1762300800000,"label":"Launched on Product Hunt"}}}},"responses":{"201":{"description":"Annotation created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Annotation"},"example":{"id":"ann_01jgq0b1h3xk2m8v9n4p5q6r7s","ts":1762300800000,"label":"Launched on Product Hunt","source":"manual"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/annotations/{aid}":{"delete":{"tags":["Annotations"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Delete an annotation","description":"Removes an annotation.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"ann_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"aid","in":"path"}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/share-links":{"get":{"tags":["Share links"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"List share links","description":"Public read-only dashboard links for the site. Password hashes are never returned.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Share links","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/ShareLink"}}},"required":["results"]},"example":{"results":[{"id":"shr_01jgq0b1h3xk2m8v9n4p5q6r7s","site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","slug":"k3j9xq2mtv","has_password":false,"hide_revenue":true,"expires_at":null,"url":"https://realific.app/share/k3j9xq2mtv"}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"post":{"tags":["Share links"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Create a share link","description":"Creates a public dashboard link, optionally password-protected, optionally hiding revenue, optionally expiring.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"password":{"type":"string","minLength":4,"maxLength":128},"hide_revenue":{"type":"boolean","default":false},"expires_at":{"type":"integer"}}},"example":{"hide_revenue":true,"password":"open sesame"}}}},"responses":{"201":{"description":"Share link created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLink"},"example":{"id":"shr_01jgq0b1h3xk2m8v9n4p5q6r7s","site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","slug":"k3j9xq2mtv","has_password":false,"hide_revenue":true,"expires_at":null,"url":"https://realific.app/share/k3j9xq2mtv"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/share-links/{sid}":{"delete":{"tags":["Share links"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Revoke a share link","description":"Deletes the link; the public URL stops working immediately.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"shr_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"sid","in":"path"}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/reports":{"get":{"tags":["Reports"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"List scheduled reports","description":"Email, Slack or Discord digests scheduled for the site.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Reports","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Report"}}},"required":["results"]},"example":{"results":[{"id":"rep_01jgq0b1h3xk2m8v9n4p5q6r7s","channel":"email","target":"ada@example.com","cadence":"weekly","next_run_at":1762750800000}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"post":{"tags":["Reports"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Schedule a report","description":"Schedules a daily, weekly or monthly digest. Email reports need Starter+, Slack/Discord need Growth+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"channel":{"type":"string","enum":["email","slack","discord"]},"target":{"type":"string","minLength":3,"maxLength":512},"cadence":{"type":"string","enum":["daily","weekly","monthly"]}},"required":["channel","target","cadence"]},"example":{"channel":"email","target":"ada@example.com","cadence":"weekly"}}}},"responses":{"201":{"description":"Report scheduled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Report"},"example":{"id":"rep_01jgq0b1h3xk2m8v9n4p5q6r7s","channel":"email","target":"ada@example.com","cadence":"weekly","next_run_at":1762750800000}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/reports/{rid}":{"delete":{"tags":["Reports"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Delete a report","description":"Stops a scheduled report.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"rep_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"rid","in":"path"}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/alerts":{"get":{"tags":["Alerts"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"List alerts","description":"Traffic spike/drop, new payment and goal threshold alerts for the site.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Alerts","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Alert"}}},"required":["results"]},"example":{"results":[{"id":"alr_01jgq0b1h3xk2m8v9n4p5q6r7s","type":"traffic_spike","channel":"slack","target":"https://hooks.slack.com/services/T000/B000/XXX","threshold":{"percent":50},"last_fired_at":null,"created_at":1762300800000}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"post":{"tags":["Alerts"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Create an alert","description":"Creates an alert delivered by email, Slack, Discord or webhook. Slack/Discord need the Growth plan.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":{"type":"string","enum":["traffic_spike","traffic_drop","new_payment","goal_threshold"]},"channel":{"type":"string","enum":["email","slack","discord","webhook"]},"target":{"type":"string","minLength":3,"maxLength":512},"threshold":{"type":"object","properties":{"percent":{"type":"number","minimum":1,"maximum":1000},"goal_id":{"type":"string"},"count":{"type":"integer"}},"default":{}}},"required":["type","channel","target"]},"example":{"type":"traffic_spike","channel":"email","target":"ada@example.com","threshold":{"percent":50}}}}},"responses":{"201":{"description":"Alert created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Alert"},"example":{"id":"alr_01jgq0b1h3xk2m8v9n4p5q6r7s","type":"traffic_spike","channel":"slack","target":"https://hooks.slack.com/services/T000/B000/XXX","threshold":{"percent":50},"last_fired_at":null,"created_at":1762300800000}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/alerts/{aid}":{"delete":{"tags":["Alerts"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Delete an alert","description":"Removes an alert.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"alr_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"aid","in":"path"}],"responses":{"204":{"description":"Deleted"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/integrations":{"get":{"tags":["Integrations"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"List integrations","description":"Connected revenue providers and Search Console. Secrets and tokens are never returned.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Integrations","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Integration"}}},"required":["results"]},"example":{"results":[{"provider":"stripe","status":"active","last_sync_at":1762300800000,"last_error":null,"config":{"account_name":"Acme"}}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"post":{"tags":["Integrations"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Connect an integration","description":"Lemon Squeezy, Paddle, Polar and Shopify (or a direct Stripe webhook) paste their webhook signing secret, stored AES-GCM encrypted. Returns the webhook URL to configure at the provider. Free plan: one revenue provider.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string","enum":["stripe","lemonsqueezy","paddle","polar","shopify","api","search_console","github"]},"secret":{"type":"string","maxLength":4096},"config":{"type":"object","additionalProperties":{}}},"required":["provider"]},"example":{"provider":"lemonsqueezy","secret":"whsec_…"}}}},"responses":{"201":{"description":"Connected","content":{"application/json":{"schema":{"type":"object","properties":{"provider":{"type":"string"},"webhook_url":{"type":"string"}},"required":["provider","webhook_url"]},"example":{"provider":"lemonsqueezy","webhook_url":"https://api.realific.app/webhooks/lemonsqueezy/site_01jgq0b1h3xk2m8v9n4p5q6r7s"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/integrations/{provider}":{"delete":{"tags":["Integrations"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Disconnect an integration","description":"Deletes the stored secret/token. Already-ingested payments are kept.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["stripe","lemonsqueezy","paddle","polar","shopify","api","search_console","search-console","github"],"example":"stripe"},"required":true,"name":"provider","in":"path"}],"responses":{"204":{"description":"Disconnected"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/integrations/stripe/connect":{"get":{"tags":["Integrations"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Stripe Connect URL","description":"Returns the Stripe Connect OAuth URL (read-only scope). The callback stores the encrypted access token and the connected account id.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Authorize URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]},"example":{"url":"https://connect.stripe.com/oauth/authorize?response_type=code&client_id=ca_…&scope=read_only&state=…"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/integrations/stripe/callback":{"get":{"tags":["Integrations"],"summary":"Stripe Connect callback","description":"OAuth redirect target. Exchanges the code, stores the encrypted token and redirects back to the site revenue settings.","parameters":[{"schema":{"type":"string"},"required":false,"name":"code","in":"query"},{"schema":{"type":"string"},"required":false,"name":"state","in":"query"},{"schema":{"type":"string"},"required":false,"name":"error","in":"query"}],"responses":{"302":{"description":"Redirect to `${APP_URL}/app/{site_id}/settings/revenue`"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/integrations/search-console/connect":{"get":{"tags":["Integrations"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Search Console connect URL","description":"Google OAuth URL with the `webmasters.readonly` scope and offline access. Growth plan and above.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Authorize URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}},"required":["url"]},"example":{"url":"https://accounts.google.com/o/oauth2/v2/auth?…"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/app/integrations/google/callback":{"get":{"tags":["Integrations"],"summary":"Google (Search Console) callback","description":"OAuth redirect target. Stores the encrypted refresh token and redirects back to the site settings.","parameters":[{"schema":{"type":"string"},"required":false,"name":"code","in":"query"},{"schema":{"type":"string"},"required":false,"name":"state","in":"query"},{"schema":{"type":"string"},"required":false,"name":"error","in":"query"}],"responses":{"302":{"description":"Redirect to `${APP_URL}/app/{site_id}/settings/integrations`"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/integrations/{provider}/backfill":{"post":{"tags":["Integrations"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Backfill payments","description":"Starts the durable backfill workflow importing the last 90 days of payments from the provider.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","enum":["stripe","lemonsqueezy","paddle","polar","shopify","api","search_console","search-console","github"],"example":"stripe"},"required":true,"name":"provider","in":"path"}],"responses":{"202":{"description":"Backfill started","content":{"application/json":{"schema":{"type":"object","properties":{"workflow_id":{"type":"string"}},"required":["workflow_id"]},"example":{"workflow_id":"wf_01jgq0b1h3xk2m8v9n4p5q6r7s"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/search-console":{"get":{"tags":["Integrations"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Search Console keywords","description":"Top queries from Google Search Console. `est_revenue` = the keyword's share of clicks x organic-search revenue attributed in the range.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$","example":"2026-10-01"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$","example":"2026-10-31"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"Keywords","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"type":"object","properties":{"keyword":{"type":"string"},"clicks":{"type":"number"},"impressions":{"type":"number"},"ctr":{"type":"number"},"position":{"type":"number"},"est_revenue":{"type":"number"}},"required":["keyword","clicks","impressions","ctr","position","est_revenue"]}}},"required":["results"]},"example":{"results":[{"keyword":"privacy analytics","clicks":120,"impressions":4000,"ctr":0.03,"position":4.2,"est_revenue":240}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/exports":{"post":{"tags":["Exports"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Request a raw export","description":"Queues an export of raw events (CSV or Parquet) built by the export workflow from the R2 archive.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"},"format":{"type":"string","enum":["csv","parquet"],"default":"csv"},"email":{"type":"boolean","default":true}},"required":["from","to"]},"example":{"from":"2026-10-01","to":"2026-10-31","format":"csv"}}}},"responses":{"202":{"description":"Export queued","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"}},"required":["id","status"]},"example":{"id":"exp_01jgq0b1h3xk2m8v9n4p5q6r7s","status":"queued"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}},"get":{"tags":["Exports"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"List exports","description":"Recent exports; finished ones carry a signed download URL valid for 24 hours.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Exports","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Export"}}},"required":["results"]},"example":{"results":[{"id":"exp_01jgq0b1h3xk2m8v9n4p5q6r7s","status":"done","format":"csv","from":1759276800000,"to":1761955199999,"url":"https://api.realific.app/v1/sites/site_…/exports/exp_…/download?exp=…&sig=…","size_bytes":1048576,"created_at":1762300800000}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/exports/{eid}":{"get":{"tags":["Exports"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Get an export","description":"Export status; `url` is present once the export is done.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"exp_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"eid","in":"path"}],"responses":{"200":{"description":"Export","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Export"},"example":{"id":"exp_01jgq0b1h3xk2m8v9n4p5q6r7s","status":"done","format":"csv","from":1759276800000,"to":1761955199999,"url":"https://api.realific.app/v1/sites/site_…/exports/exp_…/download?exp=…&sig=…","size_bytes":1048576,"created_at":1762300800000}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/exports/{eid}/download":{"get":{"tags":["Exports"],"summary":"Download an export","description":"Streams the export file from R2. Authorised by the HMAC signature in the URL (no session needed); links expire after 24 hours.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"exp_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"eid","in":"path"},{"schema":{"type":["integer","null"]},"required":false,"name":"exp","in":"query"},{"schema":{"type":"string","minLength":64,"maxLength":64},"required":true,"name":"sig","in":"query"}],"responses":{"200":{"description":"The export file","content":{"text/csv":{"schema":{"type":"string"}},"application/octet-stream":{"schema":{"type":"string"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/sites/{id}/dsr/delete":{"post":{"tags":["Exports"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Data subject deletion","description":"Deletes a visitor or customer by visitor id, user id or email (hashed with the org pepper before lookup) across D1 and R2 via the `dsr-delete` workflow. Requires `admin`+.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"visitor_id":{"type":"string","maxLength":64},"user_id":{"type":"string","maxLength":128},"email":{"type":"string","format":"email"}}},"example":{"email":"customer@example.com"}}}},"responses":{"202":{"description":"Deletion started","content":{"application/json":{"schema":{"type":"object","properties":{"workflow_id":{"type":"string"}},"required":["workflow_id"]},"example":{"workflow_id":"wf_01jgq0b1h3xk2m8v9n4p5q6r7s"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/stats/aggregate":{"get":{"tags":["Stats"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"KPI totals","description":"Visitors, pageviews, sessions, bounce rate, duration, revenue and conversion KPIs for the range, with optional comparison (`compare=previous|year`). Unfiltered ranges read rollups; filtered ranges query raw events. Requires `stats:read`.","parameters":[{"schema":{"type":"string"},"required":true,"name":"site_id","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"to","in":"query"},{"schema":{"type":"string","maxLength":64,"default":"UTC"},"required":false,"name":"tz","in":"query"},{"schema":{"type":"string","enum":["previous","year","none"],"default":"none"},"required":false,"name":"compare","in":"query"},{"schema":{"type":"string"},"required":false,"name":"filters","in":"query"},{"schema":{"type":"string","enum":["hour","day","week","month"]},"required":false,"name":"interval","in":"query"},{"schema":{"type":"string","enum":["last_non_direct","first_touch","linear"],"default":"last_non_direct"},"required":false,"name":"attribution","in":"query"}],"responses":{"200":{"description":"Aggregate","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AggregateResponse"},"example":{"current":{"visitors":4210,"pageviews":9800,"sessions":5100,"bounce_rate":0.42,"avg_duration":74.5,"revenue":1890,"net_revenue":1840,"conversions":61,"conversion_rate":0.0145,"rpv":0.45,"customers":61},"previous":{"visitors":3900,"pageviews":9800,"sessions":5100,"bounce_rate":0.42,"avg_duration":74.5,"revenue":1890,"net_revenue":1840,"conversions":61,"conversion_rate":0.0145,"rpv":0.45,"customers":61},"change":{"visitors":0.079},"meta":{"currency":"USD","sampled":false,"from":"2026-10-01T00:00:00.000Z","to":"2026-10-31T23:59:59.999Z","source":"rollup"}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/stats/timeseries":{"get":{"tags":["Stats"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Timeseries","description":"Metrics per interval bucket (auto-selected when `interval` is omitted), the comparison series, and annotations in the range.","parameters":[{"schema":{"type":"string"},"required":true,"name":"site_id","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"to","in":"query"},{"schema":{"type":"string","maxLength":64,"default":"UTC"},"required":false,"name":"tz","in":"query"},{"schema":{"type":"string","enum":["previous","year","none"],"default":"none"},"required":false,"name":"compare","in":"query"},{"schema":{"type":"string"},"required":false,"name":"filters","in":"query"},{"schema":{"type":"string","enum":["hour","day","week","month"]},"required":false,"name":"interval","in":"query"},{"schema":{"type":"string","enum":["last_non_direct","first_touch","linear"],"default":"last_non_direct"},"required":false,"name":"attribution","in":"query"}],"responses":{"200":{"description":"Timeseries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeseriesResponse"},"example":{"results":[{"ts":1759276800000,"visitors":140,"pageviews":320,"sessions":170,"revenue":63,"conversions":2,"bounce_rate":0.4,"avg_duration":70}],"previous":null,"interval":"day","annotations":[{"ts":1759276800000,"label":"Launch"}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/stats/breakdown":{"get":{"tags":["Stats"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Breakdown by dimension","description":"Top-N rows for one allow-listed dimension with revenue attributed by the selected model. `dimension=source` rows include a display `label` and a `favicon` URL; `dimension=goal` returns one row per goal. Paginate with `next_cursor`.","parameters":[{"schema":{"type":"string"},"required":true,"name":"site_id","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"to","in":"query"},{"schema":{"type":"string","maxLength":64,"default":"UTC"},"required":false,"name":"tz","in":"query"},{"schema":{"type":"string","enum":["previous","year","none"],"default":"none"},"required":false,"name":"compare","in":"query"},{"schema":{"type":"string"},"required":false,"name":"filters","in":"query"},{"schema":{"type":"string","enum":["hour","day","week","month"]},"required":false,"name":"interval","in":"query"},{"schema":{"type":"string","enum":["last_non_direct","first_touch","linear"],"default":"last_non_direct"},"required":false,"name":"attribution","in":"query"},{"schema":{"type":"string","enum":["channel","source","referrer","utm_source","utm_medium","utm_campaign","utm_term","utm_content","page","entry_page","exit_page","hostname","country","region","city","browser","os","device","screen","lang","goal","event"]},"required":true,"name":"dimension","in":"query"},{"schema":{"type":"string"},"required":false,"name":"metrics","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":10},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Breakdown","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"},"example":{"results":[{"value":"x.com","label":"x.com","favicon":"https://icons.duckduckgo.com/ip3/x.com.ico","visitors":4210,"revenue":1890,"conversion_rate":0.021,"rpv":0.45}],"next_cursor":null,"meta":{"currency":"USD","sampled":false,"dimension":"source"}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/stats/realtime":{"get":{"tags":["Stats"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Realtime","description":"Visitors in the last 5 minutes, the latest live feed from the SiteLive Durable Object, and top pages, sources and countries.","parameters":[{"schema":{"type":"string","example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"site_id","in":"query"}],"responses":{"200":{"description":"Realtime","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RealtimeResponse"},"example":{"live":12,"feed":[{"kind":"pageview","ts":1762300800000,"visitor_id":"v_3f2a…","pathname":"/pricing","name":null,"country":"DE","city":"Berlin","channel":"social","referrer_domain":"x.com","device":"mobile","revenue_cents":null,"currency":null}],"top_pages":[{"value":"/pricing","visitors":4}],"top_sources":[{"value":"x.com","visitors":5}],"top_countries":[{"value":"DE","visitors":6}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/revenue/summary":{"get":{"tags":["Revenue"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Revenue summary","description":"Revenue, refunds, new vs renewal, customers, ARPU, MRR, LTV and churn for the range, plus the comparison period when `compare` is set.","parameters":[{"schema":{"type":"string"},"required":true,"name":"site_id","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"to","in":"query"},{"schema":{"type":"string","maxLength":64,"default":"UTC"},"required":false,"name":"tz","in":"query"},{"schema":{"type":"string","enum":["previous","year","none"],"default":"none"},"required":false,"name":"compare","in":"query"},{"schema":{"type":"string"},"required":false,"name":"filters","in":"query"},{"schema":{"type":"string","enum":["hour","day","week","month"]},"required":false,"name":"interval","in":"query"},{"schema":{"type":"string","enum":["last_non_direct","first_touch","linear"],"default":"last_non_direct"},"required":false,"name":"attribution","in":"query"}],"responses":{"200":{"description":"Summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevenueSummaryResponse"},"example":{"revenue":1890,"net_revenue":1840,"new_revenue":900,"renewal_revenue":990,"refunds":50,"customers":61,"new_customers":30,"arpu":30.98,"mrr":1200,"ltv":310,"churn_rate":0.1,"conversion_rate":0.0145,"rpv":0.45,"currency":"USD","previous":null}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/revenue/payments":{"get":{"tags":["Revenue"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Payments","description":"Payments in the range, newest first, each with its first and last (non-direct) touch. Customer emails are only ever stored as peppered hashes.","parameters":[{"schema":{"type":"string","example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"site_id","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"to","in":"query"},{"schema":{"type":"string","maxLength":64,"default":"UTC"},"required":false,"name":"tz","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Payments","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/PaymentWithTouches"}},"next_cursor":{"type":["string","null"]}},"required":["results","next_cursor"]},"example":{"results":[],"next_cursor":null}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/customers":{"get":{"tags":["Customers"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Customers","description":"Paying customers in the range, most recent first, with lifetime revenue in the site currency and their last attributed channel and source.","parameters":[{"schema":{"type":"string","example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"site_id","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"to","in":"query"},{"schema":{"type":"string","maxLength":64,"default":"UTC"},"required":false,"name":"tz","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Customers","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Customer"}},"next_cursor":{"type":["string","null"]}},"required":["results","next_cursor"]},"example":{"results":[{"visitor_id":"v_3f2a…","user_id":"u_42","email_hash":null,"first_ts":1759276800000,"last_ts":1762300800000,"revenue_cents":4900,"payments":1,"last_channel":"social","last_source":"x.com"}],"next_cursor":null}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/customers/{visitorId}/journey":{"get":{"tags":["Customers"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Customer journey","description":"Every session, custom event, identify call and payment for one customer in time order. Use `-` as `visitorId` when only `user_id` is known.","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"v_3f2a9c"},"required":true,"name":"visitorId","in":"path"},{"schema":{"type":"string","example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"site_id","in":"query"},{"schema":{"type":"string","maxLength":128},"required":false,"name":"user_id","in":"query"}],"responses":{"200":{"description":"Journey","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"oneOf":[{"type":"object","properties":{"kind":{"type":"string","enum":["session"]},"ts":{"type":"number"},"session_id":{"type":"string"},"channel":{"type":"string"},"referrer_domain":{"type":["string","null"]},"utm_source":{"type":["string","null"]},"utm_campaign":{"type":["string","null"]},"entry_path":{"type":["string","null"]},"pages":{"type":"array","items":{"type":"string"}},"country":{"type":["string","null"]},"device":{"type":["string","null"]},"duration_ms":{"type":"number"}},"required":["kind","ts","session_id","channel","referrer_domain","utm_source","utm_campaign","entry_path","pages","country","device","duration_ms"]},{"type":"object","properties":{"kind":{"type":"string","enum":["event"]},"ts":{"type":"number"},"name":{"type":"string"},"props":{"type":["object","null"],"additionalProperties":{}}},"required":["kind","ts","name","props"]},{"type":"object","properties":{"kind":{"type":"string","enum":["identify"]},"ts":{"type":"number"},"user_id":{"type":"string"}},"required":["kind","ts","user_id"]},{"type":"object","properties":{"kind":{"type":"string","enum":["payment"]},"ts":{"type":"number"},"amount_site_cents":{"type":"number"},"currency":{"type":"string"},"type":{"type":"string"},"provider":{"type":"string"}},"required":["kind","ts","amount_site_cents","currency","type","provider"]}]}}},"required":["items"]},"example":{"items":[{"kind":"payment","ts":1762300800000,"amount_site_cents":4900,"currency":"USD","type":"new","provider":"stripe"}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/events":{"post":{"tags":["Ingestion"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Send server-side events","description":"Accepts one `ServerEvent` or a batch of up to 100. Events are enriched (URL/UTM parsing, referrer, channel, UA, bot flag) and queued for the processor. `site_id` may be omitted when the API key is restricted to one site. `visitor_id` defaults to a hash of `user_id`; `session_id` defaults to a hash of the visitor and hour. Requires `events:write`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"events":{"type":"array","items":{"type":"object","properties":{"site_id":{"type":"string"},"type":{"type":"string","enum":["pageview","event","payment","identify"],"default":"event"},"name":{"type":"string","maxLength":64},"url":{"type":"string","maxLength":2048},"referrer":{"type":"string","maxLength":2048},"visitor_id":{"type":"string","maxLength":64},"user_id":{"type":"string","maxLength":128},"session_id":{"type":"string","maxLength":64},"props":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":255},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"null"}]}},"ts":{"type":"integer"},"event_id":{"type":"string","minLength":16,"maxLength":32},"country":{"type":"string","minLength":2,"maxLength":2},"user_agent":{"type":"string","maxLength":512}}},"minItems":1,"maxItems":100}},"required":["events"]},{"type":"object","properties":{"site_id":{"type":"string"},"type":{"type":"string","enum":["pageview","event","payment","identify"],"default":"event"},"name":{"type":"string","maxLength":64},"url":{"type":"string","maxLength":2048},"referrer":{"type":"string","maxLength":2048},"visitor_id":{"type":"string","maxLength":64},"user_id":{"type":"string","maxLength":128},"session_id":{"type":"string","maxLength":64},"props":{"type":"object","additionalProperties":{"anyOf":[{"type":"string","maxLength":255},{"type":"number"},{"type":"boolean"},{"type":"null"},{"type":"null"}]}},"ts":{"type":"integer"},"event_id":{"type":"string","minLength":16,"maxLength":32},"country":{"type":"string","minLength":2,"maxLength":2},"user_agent":{"type":"string","maxLength":512}}}]},"example":{"site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","type":"event","name":"signup","user_id":"u_42","url":"https://example.com/welcome?utm_source=newsletter","props":{"plan":"pro"}}}}},"responses":{"202":{"description":"Queued","content":{"application/json":{"schema":{"type":"object","properties":{"accepted":{"type":"number"}},"required":["accepted"]},"example":{"accepted":1}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/v1/payments":{"post":{"tags":["Ingestion"],"security":[{"bearer":[]},{"cookie":[]}],"summary":"Record a payment","description":"Generic payment ingestion for providers without a webhook integration. `amount` is in major units (49.00); refunds use `type=refund`. The amount is converted to the site currency, the visitor is resolved (visitor_id -> user_id -> email hash within 30 days) and first/last touch are attributed. Idempotent on `payment_id`: a repeat returns 200 with the original id. Requires `payments:write`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"site_id":{"type":"string"},"payment_id":{"type":"string","minLength":1,"maxLength":128},"amount":{"type":"number"},"currency":{"type":"string","minLength":3,"maxLength":3},"type":{"type":"string","enum":["new","renewal","refund","one_time"],"default":"one_time"},"ts":{"type":"integer"},"visitor_id":{"type":"string","maxLength":64},"user_id":{"type":"string","maxLength":128},"email":{"type":"string","format":"email"},"customer_id":{"type":"string","maxLength":128},"subscription_id":{"type":"string","maxLength":128},"product":{"type":"string","maxLength":128}},"required":["payment_id","amount","currency"]},"example":{"site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","payment_id":"inv_1001","amount":49,"currency":"EUR","type":"new","visitor_id":"v_3f2a9c","email":"customer@example.com"}}}},"responses":{"200":{"description":"Duplicate (already recorded)","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"duplicate":{"type":"boolean"}},"required":["id"]},"example":{"id":"pay_3f9c2a1b0d8e7f6a5b4c3d2e1f","duplicate":true}}}},"201":{"description":"Recorded","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string"},"duplicate":{"type":"boolean"}},"required":["id"]},"example":{"id":"pay_3f9c2a1b0d8e7f6a5b4c3d2e1f"}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/webhooks/polar-billing":{"post":{"tags":["Webhooks"],"summary":"Realific billing webhook (Polar)","description":"Polar events for Realific's own subscriptions (`subscription.created|updated|active|canceled|uncanceled|revoked|past_due`). Standard Webhooks signature verified with `POLAR_WEBHOOK_SECRET` (5-minute window), de-duplicated by `webhook-id`. The plan, tier and interval come from the subscribed product's `realific_*` metadata; the org from the customer's `external_id`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}},"example":{"type":"subscription.active","timestamp":"2026-11-05T12:00:00Z","data":{"id":"sub_1","status":"active","customer_id":"cus_1","current_period_end":"2026-12-05T12:00:00Z","cancel_at_period_end":false,"ended_at":null,"customer":{"external_id":"org_01jgq0b1h3xk2m8v9n4p5q6r7s"},"product":{"id":"prod_1","metadata":{"realific_plan":"growth","realific_tier":"100k","realific_interval":"month"}}}}}}},"responses":{"200":{"description":"Received","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean","enum":[true]},"duplicate":{"type":"boolean"},"payments":{"type":"number"}},"required":["received"]},"example":{"received":true}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/webhooks/{provider}/{siteId}":{"post":{"tags":["Webhooks"],"summary":"Payment provider webhook","description":"Stripe (`Stripe-Signature`, or Stripe Connect with the account-level secret), Lemon Squeezy (`X-Signature`), Paddle (`Paddle-Signature`), Polar (Standard Webhooks) and Shopify (`X-Shopify-Hmac-Sha256`). Signatures are compared in constant time with a 5-minute replay window, deliveries are de-duplicated by provider event id, and payments are normalised, attributed to the visitor (metadata `realific_visitor_id` -> user id -> email hash) and stored.","parameters":[{"schema":{"type":"string","enum":["stripe","lemonsqueezy","paddle","polar","shopify"],"example":"stripe"},"required":true,"name":"provider","in":"path"},{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"siteId","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{}},"example":{"id":"evt_1","type":"checkout.session.completed","data":{"object":{"id":"cs_1","mode":"payment","payment_status":"paid","amount_total":4900,"currency":"usd","payment_intent":"pi_1","metadata":{"realific_visitor_id":"v_3f2a9c"},"customer_details":{"email":"customer@example.com"},"created":1762300800}}}}}},"responses":{"200":{"description":"Received","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean","enum":[true]},"duplicate":{"type":"boolean"},"payments":{"type":"number"}},"required":["received"]},"example":{"received":true,"payments":1}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/share/{slug}":{"get":{"tags":["Share"],"summary":"Share link info","description":"Public metadata for a share link: site, whether revenue is hidden, password state, white-label settings (Agency plan) and whether the Realific badge must be shown (Free plan).","parameters":[{"schema":{"type":"string","minLength":4,"maxLength":64,"example":"k3j9xq2mtv"},"required":true,"name":"slug","in":"path"}],"responses":{"200":{"description":"Share link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareInfo"},"example":{"site":{"name":"Example","domain":"example.com","timezone":"UTC","currency":"USD"},"hide_revenue":false,"has_password":true,"unlocked":false,"white_label":null,"badge":true}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/share/{slug}/unlock":{"post":{"tags":["Share"],"summary":"Unlock a share link","description":"Checks the password and sets the `rf_share_{slug}` cookie. Rate limited to 10 attempts per minute per link and IP.","parameters":[{"schema":{"type":"string","minLength":4,"maxLength":64,"example":"k3j9xq2mtv"},"required":true,"name":"slug","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"password":{"type":"string","minLength":1,"maxLength":128}},"required":["password"]},"example":{"password":"open sesame"}}}},"responses":{"204":{"description":"Unlocked"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/share/{slug}/stats/aggregate":{"get":{"tags":["Share"],"summary":"Shared KPI totals","description":"Same as `/v1/stats/aggregate` without `site_id`; revenue fields are 0 when the link hides revenue.","parameters":[{"schema":{"type":"string","minLength":4,"maxLength":64,"example":"k3j9xq2mtv"},"required":true,"name":"slug","in":"path"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"to","in":"query"},{"schema":{"type":"string","maxLength":64,"default":"UTC"},"required":false,"name":"tz","in":"query"},{"schema":{"type":"string","enum":["previous","year","none"],"default":"none"},"required":false,"name":"compare","in":"query"},{"schema":{"type":"string"},"required":false,"name":"filters","in":"query"},{"schema":{"type":"string","enum":["hour","day","week","month"]},"required":false,"name":"interval","in":"query"},{"schema":{"type":"string","enum":["last_non_direct","first_touch","linear"],"default":"last_non_direct"},"required":false,"name":"attribution","in":"query"}],"responses":{"200":{"description":"Aggregate","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AggregateResponse"},"example":{"current":{"visitors":4210,"pageviews":9800,"sessions":5100,"bounce_rate":0.42,"avg_duration":74.5,"revenue":1890,"net_revenue":1840,"conversions":61,"conversion_rate":0.0145,"rpv":0.45,"customers":61},"previous":{"visitors":3900,"pageviews":9800,"sessions":5100,"bounce_rate":0.42,"avg_duration":74.5,"revenue":1890,"net_revenue":1840,"conversions":61,"conversion_rate":0.0145,"rpv":0.45,"customers":61},"change":{"visitors":0.079},"meta":{"currency":"USD","sampled":false,"from":"2026-10-01T00:00:00.000Z","to":"2026-10-31T23:59:59.999Z","source":"rollup"}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/share/{slug}/stats/timeseries":{"get":{"tags":["Share"],"summary":"Shared timeseries","description":"Same as `/v1/stats/timeseries` without `site_id`.","parameters":[{"schema":{"type":"string","minLength":4,"maxLength":64,"example":"k3j9xq2mtv"},"required":true,"name":"slug","in":"path"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"to","in":"query"},{"schema":{"type":"string","maxLength":64,"default":"UTC"},"required":false,"name":"tz","in":"query"},{"schema":{"type":"string","enum":["previous","year","none"],"default":"none"},"required":false,"name":"compare","in":"query"},{"schema":{"type":"string"},"required":false,"name":"filters","in":"query"},{"schema":{"type":"string","enum":["hour","day","week","month"]},"required":false,"name":"interval","in":"query"},{"schema":{"type":"string","enum":["last_non_direct","first_touch","linear"],"default":"last_non_direct"},"required":false,"name":"attribution","in":"query"}],"responses":{"200":{"description":"Timeseries","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeseriesResponse"},"example":{"results":[{"ts":1759276800000,"visitors":140,"pageviews":320,"sessions":170,"revenue":63,"conversions":2,"bounce_rate":0.4,"avg_duration":70}],"previous":null,"interval":"day","annotations":[{"ts":1759276800000,"label":"Launch"}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/share/{slug}/stats/breakdown":{"get":{"tags":["Share"],"summary":"Shared breakdown","description":"Same as `/v1/stats/breakdown` without `site_id`.","parameters":[{"schema":{"type":"string","minLength":4,"maxLength":64,"example":"k3j9xq2mtv"},"required":true,"name":"slug","in":"path"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}(T.*)?$"},"required":true,"name":"to","in":"query"},{"schema":{"type":"string","maxLength":64,"default":"UTC"},"required":false,"name":"tz","in":"query"},{"schema":{"type":"string","enum":["previous","year","none"],"default":"none"},"required":false,"name":"compare","in":"query"},{"schema":{"type":"string"},"required":false,"name":"filters","in":"query"},{"schema":{"type":"string","enum":["hour","day","week","month"]},"required":false,"name":"interval","in":"query"},{"schema":{"type":"string","enum":["last_non_direct","first_touch","linear"],"default":"last_non_direct"},"required":false,"name":"attribution","in":"query"},{"schema":{"type":"string","enum":["channel","source","referrer","utm_source","utm_medium","utm_campaign","utm_term","utm_content","page","entry_page","exit_page","hostname","country","region","city","browser","os","device","screen","lang","goal","event"]},"required":true,"name":"dimension","in":"query"},{"schema":{"type":"string"},"required":false,"name":"metrics","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":500,"default":10},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string"},"required":false,"name":"cursor","in":"query"}],"responses":{"200":{"description":"Breakdown","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakdownResponse"},"example":{"results":[{"value":"x.com","label":"x.com","favicon":"https://icons.duckduckgo.com/ip3/x.com.ico","visitors":4210,"revenue":1890,"conversion_rate":0.021,"rpv":0.45}],"next_cursor":null,"meta":{"currency":"USD","sampled":false,"dimension":"source"}}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/share/{slug}/stats/realtime":{"get":{"tags":["Share"],"summary":"Shared realtime","description":"Same as `/v1/stats/realtime` without `site_id`.","parameters":[{"schema":{"type":"string","minLength":4,"maxLength":64,"example":"k3j9xq2mtv"},"required":true,"name":"slug","in":"path"}],"responses":{"200":{"description":"Realtime","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RealtimeResponse"},"example":{"live":12,"feed":[{"kind":"pageview","ts":1762300800000,"visitor_id":"v_3f2a…","pathname":"/pricing","name":null,"country":"DE","city":"Berlin","channel":"social","referrer_domain":"x.com","device":"mobile","revenue_cents":null,"currency":null}],"top_pages":[{"value":"/pricing","visitors":4}],"top_sources":[{"value":"x.com","visitors":5}],"top_countries":[{"value":"DE","visitors":6}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/share/{slug}/goals":{"get":{"tags":["Share"],"summary":"Shared goals","description":"Goal definitions for the goals card of a shared dashboard.","parameters":[{"schema":{"type":"string","minLength":4,"maxLength":64,"example":"k3j9xq2mtv"},"required":true,"name":"slug","in":"path"}],"responses":{"200":{"description":"Goals","content":{"application/json":{"schema":{"type":"object","properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/Goal"}}},"required":["results"]},"example":{"results":[{"id":"goal_01jgq0b1h3xk2m8v9n4p5q6r7s","site_id":"site_01jgq0b1h3xk2m8v9n4p5q6r7s","name":"Signup","type":"event","match":{"type":"event","name":"signup"},"created_at":1762300800000}]}}}},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}},"/ws/sites/{id}/live":{"get":{"tags":["Realtime"],"summary":"Realtime WebSocket","description":"Upgrades to the site's `SiteLive` Durable Object. Authenticate with the session cookie, a Bearer API key (`stats:read`), or `?share=slug` for share links. Server messages are `LiveMessage` (`hello` with the live count and last 50 items, then `event` / `count`, `ping` every 30 s).","parameters":[{"schema":{"type":"string","minLength":1,"maxLength":64,"example":"site_01jgq0b1h3xk2m8v9n4p5q6r7s"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","maxLength":64},"required":false,"name":"share","in":"query"}],"responses":{"101":{"description":"Switching protocols"},"401":{"description":"Authentication required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"unauthorized","message":"Authentication required","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"403":{"description":"Forbidden","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"forbidden","message":"Forbidden","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"not_found","message":"Not found","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"422":{"description":"Validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"validation_error","message":"Validation failed","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"426":{"description":"Upgrade required"},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":{"code":"rate_limited","message":"Rate limited","request_id":"0b6c1f2e-5f6a-4a1b-9c3d-2e4f6a8b0c1d"}}}}},"500":{"description":"Internal error"}}}}},"webhooks":{}}