{"openapi":"3.1.0","info":{"title":"fastmon API","summary":"Real-time website performance monitoring.","description":"Fastmon is a real-time website performance monitoring platform: RUM (Real User\nMonitoring), Core Web Vitals, traffic analytics, and rule-based notifications.\n\nThis document is the authoritative reference for the `v1` API. It's generated\nfrom code and updated on every release. Anything not documented here is\nunsupported.\n\n## Base URL\n\n    https://api.fastmon.eu/v1\n\n## Authentication\n\nAll `/v1/` endpoints require an authenticated principal via a **Bearer\ntoken**:\n\n    Authorization: Bearer fm_...\n\nGenerate a token from the fastmon dashboard (Account → API Token). Tokens\nare hashed server-side; only the `fm_` prefix is queryable. Lost tokens\ncannot be recovered; regenerate instead.\n\nThe two public ingest endpoints (`POST /c/{collector_hash}` and\n`GET /s/{source_hash}.js`) are unauthenticated and authorize requests via\nthe per-site hash embedded in the URL.\n\n## Response shape\n\n* **Single resource**: returned raw: `{ \"id\": \"...\", \"name\": \"...\", ... }`\n* **List**: wrapped: `{ \"data\": [...], \"meta\": { \"limit\": 50, \"offset\": 0, \"total\": 242, \"has_more\": true } }`\n* **Error**: wrapped: `{ \"error\": { \"code\": \"...\", \"message\": \"...\", \"request_id\": \"...\", \"details\": {...} } }`\n\nSee §1–§2 of `API_STANDARDS.md` for the full envelope spec.\n\n## IDs and timestamps\n\n* Resource IDs are **UUID v7** strings. Generated server-side via `uuid.uuid7()`.\n* Timestamps are **ISO 8601 UTC with `Z` suffix**: `2026-04-18T12:34:56.123456Z`.\n\n## Pagination\n\n* Default `limit=50`, max `100` on every list endpoint.\n* Most list endpoints use offset pagination: `?limit=50&offset=50`; responses\n  include `meta.total` and `meta.has_more`.\n* High-volume endpoints (notably analytics sessions and events) use **cursor**\n  pagination instead: responses carry `meta.next_cursor`, which the client\n  sends back as `?cursor=<token>` to fetch the next page. These responses do\n  not include `meta.total`.\n* Which scheme applies is visible from the response `meta` shape: check for\n  `next_cursor` (cursor) vs `offset`+`total` (offset).\n\n## Request correlation\n\nEvery response carries `X-Request-ID`. If a client sends one, the server\npropagates it; otherwise the server generates a UUID v7. The same ID is\nmirrored into `error.request_id` on failures; always include it when\nreporting issues.\n\n## Public ingest endpoints\n\n`POST /c/{collector_hash}` (beacon ingestion) and `GET /s/{source_hash}.js`\n(tracking script) are **not** under `/v1/` and are exempt from these\nstandards. They have their own wire contract documented in\n`API_STANDARDS.md` §22.\n\n## Status\n\nThe v1 API is actively developed.","contact":{"name":"fastmon","url":"https://fastmon.eu/","email":"support@fastmon.eu"},"version":"2026.7.51"},"paths":{"/v1/organizations":{"get":{"tags":["organizations"],"summary":"List Organizations","description":"List organizations the user has access to (direct or via partner).","operationId":"listOrganizations","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_OrganizationResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["organizations"],"summary":"Create Organization","description":"Create a new organization.\n\nThe user who creates the organization automatically becomes the owner with\nfull permissions. New organizations start unapproved: members can look\naround, but applications/sites (and thus data ingestion) require an admin\nto approve the org first. Users with the admin-granted `auto_approve_orgs`\nflag skip the gate — their orgs start approved.","operationId":"createOrganization","security":[{"APIKeyHeader":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}":{"get":{"tags":["organizations"],"summary":"Get Organization","description":"Get organization by ID.","operationId":"getOrganization","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["organizations"],"summary":"Update Organization","description":"Update organization. Owner-only.\n\n`ai_enabled` is a compliance-grade kill-switch: when flipped off, every\n`/v1/ai/*` endpoint returns 403 and no beacon data from this org\never reaches Mistral. Owner-level access is required so a single\nregular member can't unilaterally enable / disable AI for the whole\norganization.","operationId":"updateOrganization","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrganizationResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["organizations"],"summary":"Delete Organization","description":"Delete organization and all related data. Owner-only.\n\nIrreversibly cascades to sites, invites, partner links and memberships, so\nit requires owner-level access (matching `update`/`transfer-ownership`).\nMember-level access — including partner-org access to a client org — is not\nenough to destroy an organization.\n\n**What gets deleted:**\n- All sites belonging to the organization\n- All pending invites\n- All member associations (memberships)\n- The organization itself\n\n**What is preserved:**\n- User accounts of all members (by default)\n\n**Optional: delete_account**\n\nIf `delete_account=true` is passed as a query parameter, the current user's\naccount will also be deleted after the organization is removed.","operationId":"deleteOrganization","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"delete_account","in":"query","required":false,"schema":{"type":"boolean","description":"If true, also delete the requesting user's account","default":false,"title":"Delete Account"},"description":"If true, also delete the requesting user's account"}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/usage":{"get":{"tags":["organizations"],"summary":"Get Usage","description":"Get beacon usage for the current billing period (calendar month).\n\nPass `?by_site=true` to include per-site breakdown.","operationId":"getOrganizationUsage","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"by_site","in":"query","required":false,"schema":{"type":"boolean","description":"Include per-site breakdown","default":false,"title":"By Site"},"description":"Include per-site breakdown"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/audit-log":{"get":{"tags":["organizations"],"summary":"List Audit Log","description":"Durable trail of relevant changes for this org (consent toggles, site\ndeletion, hash rotation, ...), newest first. Owner-only.","operationId":"listOrganizationAuditLog","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"action","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/AuditAction"},{"type":"null"}],"description":"Filter by action","title":"Action"},"description":"Filter by action"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_AuditLogEntry_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/members":{"get":{"tags":["organizations","members"],"summary":"List Members","description":"List organization members.\n\nReturns all members with their roles (owner/member).","operationId":"listOrganizationMembers","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_MemberResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["organizations"],"summary":"Add Member","description":"Add a user to the organization. User must already exist.\n\nRequires *direct* membership: this seats a member with no invite handshake,\nso partner-via-partner access must not be able to inject members into a\nmanaged client org (it would route members in without their consent). A\npartner seats real users through the invite flow instead.","operationId":"addOrganizationMember","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberAdd"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemberResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict - Resource already exists or operation not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/transfer-ownership":{"post":{"tags":["organizations","members"],"summary":"Transfer Ownership","description":"Transfer ownership of the organization to another member.\n\n**Permissions:**\n- Only the current owner can transfer ownership\n- Target user must be an existing member of the organization\n\n**Process:**\n- Current owner becomes a regular member\n- Target member becomes the new owner\n- Ensures only one owner per organization at all times\n\n**Request Body:**\n- `new_owner_user_id`: UUID of the member who will become the new owner","operationId":"transferOrganizationOwnership","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OwnershipTransferRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/invites":{"get":{"tags":["organizations"],"summary":"List Invites","description":"List pending invites.","operationId":"listOrganizationInvites","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_InviteResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["organizations"],"summary":"Create Invite","description":"Create an organization invite and send email.\n\n**Request Body:**\n- `email`: Email address to invite\n- `role`: Role to assign (default: \"member\"). Assigning a privileged role\n  (anything other than \"member\") requires the caller to be an owner of the\n  org — or an owner of a partner org that manages it (the partner→customer\n  ownership handoff). Otherwise a regular member could invite a second\n  account as owner and escalate.\n\nSends an invitation email with a unique token that expires in 7 days.","operationId":"createOrganizationInvite","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict - Resource already exists or operation not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/members/{member_id}":{"delete":{"tags":["members"],"summary":"Remove Member","description":"Remove a member from the organization or leave the organization.\n\n**Permissions:**\n- Only owners can remove other members\n- Any member can leave the organization (remove themselves)\n\n**Use cases:**\n- Remove another member from your organization (owner only)\n- Leave an organization yourself (when the membership's user_id matches your own)\n\n**Behavior when multiple members exist:**\n- Only the specified member's association is removed\n- Organization, sites, and invites remain intact\n\n**Behavior when this is the LAST member:**\n- All sites are deleted\n- All pending invites are deleted\n- The organization itself is deleted\n- The user account is preserved (NOT deleted)","operationId":"removeOrganizationMember","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"member_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Member Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/sites":{"get":{"tags":["sites"],"summary":"List Sites","description":"List all sites for an organization. Filter by tag(s) (AND semantics) and/or\nby `application_id` (the app's domains).","operationId":"listSites","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"tag","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"default":[],"title":"Tag"}},{"name":"application_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Filter to the domains (sites) of one application","title":"Application Id"},"description":"Filter to the domains (sites) of one application"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_SiteResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["sites"],"summary":"Create Site","description":"Create a site (a domain) under an existing application. The embed + all\ncollection config live on the application (`application_id`, required); only\nthe domain, name, tags and the optional per-domain overrides are set here. To\ncreate a standalone site, create its application first (POST /applications),\nthen add the domain here.","operationId":"createSite","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict - Resource already exists or operation not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/sites/status":{"get":{"tags":["sites"],"summary":"Get Org Sites Status","description":"Beacon status for every site in the org in one call.\n\nOrg-scoped twin of `get_site_status` (same per-site fields), so the\ndashboard header widget can render all sites without N status calls. One\nClickHouse aggregate grouped by `site_id`; sites with no beacons still\nappear with zeroed counts. Ordering follows the site list (id/creation\norder from the SELECT). Membership is enforced by `OrgMember`.","operationId":"getOrgSitesStatus","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/OrgSiteStatusItem"},"title":"Response Getorgsitesstatus"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/tags":{"get":{"tags":["sites"],"summary":"List Tags","description":"List all unique tags in use across the organization's sites.","operationId":"listSiteTags","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"type":"string"},"title":"Response Listsitetags"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}":{"get":{"tags":["sites"],"summary":"Get Site","description":"Get site by ID.","operationId":"getSite","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["sites"],"summary":"Update Site","description":"Update a site's own (per-domain) fields. Collection config + hashes live on\nthe Application (one baked bundle per app) and are edited there, not per Site.","operationId":"updateSite","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["sites"],"summary":"Delete Site","description":"Delete site. If it was the sole domain of its application, the application\n(and its releases) is removed too; a shared application is kept for its\nsiblings.","operationId":"deleteSite","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/status":{"get":{"tags":["sites"],"summary":"Get Site Status","description":"Get site beacon status: today's count, current rate, and last beacon timestamp.","operationId":"getSiteStatus","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteStatusResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/applications":{"get":{"tags":["applications"],"summary":"List Applications","description":"List the organization's applications, each with its domain (site) count.","operationId":"listApplications","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ApplicationResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["applications"],"summary":"Create Application","description":"Provision an application: one embed whose collection config applies to every\ndomain it runs on, with the concrete Site for each beacon resolved at ingest by\nthe page-URL host. Sites are added by adopting/assigning domains (or\nauto-provision).","operationId":"createApplication","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/applications/unknown-hostnames":{"get":{"tags":["applications"],"summary":"List Unknown Hostnames","description":"Hostnames observed hitting an application that matched no registered site\n— candidates to adopt as new sites, each tagged with the application that\nobserved it. Backed by a best-effort Valkey counter (7-day TTL); empty if\nValkey is unavailable.","operationId":"listApplicationUnknownHostnames","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":200,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UnknownHostnamesResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/applications/unknown-hostnames/{hostname}":{"delete":{"tags":["applications"],"summary":"Dismiss Unknown Hostname","description":"Dismiss a discovered hostname (after adopting it, or to hide noise).\n\nRemoves it for EVERY application that observed it — once the domain is a Site\n(or the customer hid it) it's no longer a suggestion regardless of source.","operationId":"dismissApplicationUnknownHostname","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"hostname","in":"path","required":true,"schema":{"type":"string","maxLength":255,"title":"Hostname"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/applications/{app_id}":{"get":{"tags":["applications"],"summary":"Get Application","operationId":"getApplication","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["applications"],"summary":"Update Application","description":"Update an application. Config changes re-render the served bundle (cache\ninvalidated).","operationId":"updateApplication","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["applications"],"summary":"Delete Application","description":"Delete an application and all its sites (their beacon data included — the\nembed is gone, so the domains can no longer collect). The embed stops\nresolving immediately.","operationId":"deleteApplication","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/applications/{app_id}/rotate-hashes":{"post":{"tags":["applications"],"summary":"Rotate Application Hashes","description":"Rotate the application's script and collector hashes. Existing embeds stop\nworking until the snippet is updated everywhere!","operationId":"rotateApplicationHashes","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/applications/{app_id}/sites":{"get":{"tags":["applications"],"summary":"List Application Sites","description":"List the domains (sites) this application runs on.","operationId":"listApplicationSites","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_SiteResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["applications"],"summary":"Create Application Site","description":"Adopt a domain into the application as a member site. The site is a pure\ndomain/analytics unit — it carries no hashes/config of its own; the\napplication's config applies at ingest, so only the domain is needed.\nTypically fed a hostname from the discovery list; on success that hostname is\ncleared from the list.","operationId":"createApplicationSite","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApplicationSiteCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict - Resource already exists or operation not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/applications/{app_id}/sites/{site_id}":{"put":{"tags":["applications"],"summary":"Assign Application Site","description":"Move an existing site into this application. The application claims the\ndomain for ingest + releases. Re-assigning to the same application is a no-op.\n\nThe site's previous application is left in place even if it ends up with no\nsites — an empty application keeps its embed/config and can take on new\ndomains later; deleting it is an explicit action (DELETE /applications/{id}).","operationId":"assignApplicationSite","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SiteResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict - Resource already exists or operation not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/releases":{"get":{"tags":["releases"],"summary":"List Org Releases","description":"List all releases across an organization, newest first. Optionally restrict\nto one application.","operationId":"listOrgReleases","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"application_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Optional: restrict to one application","title":"Application Id"},"description":"Optional: restrict to one application"},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"To"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ReleaseResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/applications/{app_id}/releases":{"get":{"tags":["releases"],"summary":"List Application Releases","description":"List an application's releases, newest first.","operationId":"listApplicationReleases","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"To"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ReleaseResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["releases"],"summary":"Create Application Release","description":"Create a release on an application (a one-site app = that site; a multi-site\napp = a coordinated marker across all its domains).","operationId":"createApplicationRelease","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"app_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"App Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict - Resource already exists or operation not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/releases":{"get":{"tags":["releases"],"summary":"List Releases","description":"List releases for a site (its application's releases).","operationId":"listReleases","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"From"}},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"To"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_ReleaseResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["releases"],"summary":"Create Release","description":"Create a release for a site (on its application).","operationId":"createRelease","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict - Resource already exists or operation not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/releases/{release_id}":{"get":{"tags":["releases"],"summary":"Get Release","description":"Get a single release by ID.","operationId":"getRelease","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"release_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Release Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["releases"],"summary":"Update Release","description":"Update a release.","operationId":"updateRelease","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"release_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Release Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict - Resource already exists or operation not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["releases"],"summary":"Delete Release","description":"Delete a release.","operationId":"deleteRelease","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"release_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Release Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/analytics/beacons":{"post":{"tags":["analytics"],"summary":"Query Beacons Records","description":"Row-level drill-down: return individual beacons matching the filter.\n\nPaired with `/analytics/query` (which aggregates). A dashboard click on an\naggregate row sends the same filters here to get the specific beacons behind\nit. No metric aggregation: raw column values only, projected through the\n`fields` whitelist.\n\nResponse is uncached (rows change every ingest). Total-count is fetched in\nthe same round-trip via asyncio.gather so the UI knows whether pagination\nis worth showing.","operationId":"queryAnalyticsBeacons","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BeaconsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BeaconsResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/beacon-breakdowns":{"post":{"tags":["analytics"],"summary":"Query Beacon Breakdowns","description":"Get the orthogonal beacon-ingestion breakdowns: privacy class,\ndelivery channel, lifecycle stage, and tracker bundle version. See\n`BeaconBreakdownsResponse` for the semantics of each dimension.","operationId":"queryAnalyticsBeaconBreakdowns","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BeaconBreakdownsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BeaconBreakdownsResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/resource-breakdown":{"post":{"tags":["analytics"],"summary":"Query Resource Breakdown","description":"Get resource breakdown by type (script, css, img, font, other).","operationId":"queryAnalyticsResourceBreakdown","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceBreakdownRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResourceBreakdownResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/third-party":{"post":{"tags":["analytics"],"summary":"Query Third Party","description":"Top third-party domains by request count.\n\nPer-domain blocking duration is not available here; if you need a duration\nproxy, query `/analytics/query` with the `dominant_third_party_category`\ndimension.","operationId":"queryAnalyticsThirdParty","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThirdPartyRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ThirdPartyResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/server-timing":{"post":{"tags":["analytics"],"summary":"Query Server Timing","description":"Server-Timing dashboard panel: three blocks.\n\n- `cache`: cdn / origin cache-status distribution (count per status).\n- `phases`: p50/p75/p95 of the seven backend-phase durations (NULLs skipped).\n- `top_keys`: custom server-timing keys, ranked by p75.","operationId":"queryAnalyticsServerTiming","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerTimingRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServerTimingResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/fetch-xhr":{"post":{"tags":["analytics"],"summary":"Query Fetch Xhr","description":"FetchXhr (fetch/XHR) dashboard panel: three blocks.\n\n- `totals`: aggregate calls, errors, and worst-case duration.\n- `endpoints`: per-endpoint aggregates grouped by method/host/path (the\n  `other` rollup bucket is excluded, reflected only in totals), sorted by\n  impact.\n- `outliers`: the slowest individual calls.","operationId":"queryAnalyticsFetchXhr","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FetchXhrRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FetchXhrResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/fetch-xhr/detail":{"post":{"tags":["analytics"],"summary":"Query Fetch Xhr Detail","description":"Host (or endpoint) drill-down — the analogue of `/error-types/detail` (which\nkeys on `fingerprint`). Keyed by `host`; `method`/`path` are optional\nrefinements (omit for the whole host, give `path` for one endpoint).\n\nFour `ARRAY JOIN`s over `beacons FINAL` (cumulative per-pvid state → FINAL),\nsharing one scope filter (`host` [+ method] [+ path]): a summary, the\nper-endpoint list (group by method/path), the per-page breakdown (group by\nthe beacon `url`) and the individual trace calls (`fetch_xhr_outliers`, with\nstatus + the page they ran on). No 037/L1 dependency — `url` lives on the\nsame row as the Nested columns. Status distribution beyond these trace\nsamples needs the Phase-2 per-endpoint status counters.","operationId":"queryAnalyticsFetchXhrDetail","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FetchXhrDetailRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FetchXhrDetailResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/loaf":{"post":{"tags":["analytics"],"summary":"Query Loaf","description":"Get Long Animation Frames (LoAF) data.\n\nTwo-part query:\n- Summary (`total_frames`, `avg_duration`) is sourced from the cheap\n  `loaf_count` / `loaf_total_duration` Phase-3 columns.\n- Per-script breakdown (`data`) ARRAY JOINs the `loaf` Nested.","operationId":"queryAnalyticsLoAF","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoAFRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoAFResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/element-targets":{"post":{"tags":["analytics"],"summary":"Query Element Targets","description":"Rank the attributed elements (CSS selector paths) for lcp / cls / inp.","operationId":"queryAnalyticsElementTargets","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ElementTargetsRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ElementTargetsResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/error-types":{"post":{"tags":["analytics"],"summary":"Query Error Types","description":"Get breakdown of error signatures from collected beacons.\n\nReads the structured `errors` Nested column. Each beacon stores up to 5\n(type, count, sample_message, frame_hosts, frame_lines, frame_cols,\nfingerprint, is_first_party) entries; we ARRAY JOIN and aggregate by\n`fingerprint`, the canonical server-computed signature key.\n\nDisplay projections (error_type, sample_message, frames) are aggregated\nvia `any()` since within a fingerprint group they're stable by\nconstruction (the fingerprint hashes those exact inputs); using `any()`\nrather than `argMax/groupArray` keeps the query cheap.","operationId":"queryAnalyticsErrorTypes","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorTypesRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorTypesResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/error-types/detail":{"post":{"tags":["analytics"],"summary":"Query Error Detail","description":"Drill-down for a single error signature, keyed by `fingerprint`.\n\nReturns summary stats, a time series, top-N breakdowns across the requested\ndimensions, and recent sample beacons, all in one request.","operationId":"queryAnalyticsErrorDetail","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetailRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorDetailResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/experience-score":{"post":{"tags":["analytics"],"summary":"Query Experience Score","description":"Compute experience scores per visitor segment.\n\nReturns letter grades (A+ through F) and numeric scores (0.0–10.0)\nfor Desktop, Mobile, Slow Connections, and All Visitors.","operationId":"queryAnalyticsExperienceScore","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExperienceScoreRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExperienceScoreResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/histogram":{"post":{"tags":["analytics"],"summary":"Query Histogram","description":"Get histogram distribution for a metric.\n\n**Metrics:** lcp, fcp, cls, inp, ttfb, tbt, dns_lookup, tcp_connection, etc.\n\n**Buckets:** Define boundaries as array, e.g., [0, 500, 1000, 2500, 4000]\ncreates buckets: <0, 0-500, 500-1000, 1000-2500, 2500-4000, 4000+\n\n**Example for LCP histogram:**\n```json\n{\n    \"time_range\": {\"from\": \"2024-01-01\", \"to\": \"2024-01-08\"},\n    \"metric\": \"lcp\",\n    \"buckets\": [0, 500, 1000, 2500, 4000]\n}\n```","operationId":"queryAnalyticsHistogram","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistogramRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistogramResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/query":{"post":{"tags":["analytics"],"summary":"Query Analytics","description":"Execute a flexible analytics query against RUM data.\n\n**Metrics:** lcp, fcp, cls, inp, ttfb, tbt, page_load_time, requests,\n`visitors` (distinct visitors; `identity`=stitch|session picks the backing\nidentifier, stitch preferred), etc.\n\n**Aggregations:** count, avg, p50, p75, p90, p95, p99, min, max, sum\n\n**Grouping:** By time intervals (hour, day, week, month) and/or dimensions\n(browser, device_type, country, etc.)\n\n**Filters:** site_id, browser, device_type, country, url (with wildcards), etc.\n\n**Comparison:** Set compare_to to compare with previous_period, previous_week, or previous_month\n\n**Limits:**\n- Max 90 days time range\n- Max 10 metrics per query\n- Max 2 GROUP BY dimensions\n- Max 10,000 rows per response","operationId":"queryAnalytics","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsQueryRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalyticsQueryResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/visitors":{"post":{"tags":["analytics"],"summary":"Query Visitors","description":"List visitors with summary stats, grouped by the resolved `identity`\n(stitch — preferred — or session).\n\nEach row is one visitor: page count, duration, device info, and average\nperformance. Cursor paginated, ordered by (start_time DESC, id DESC).\n\nAggregate browsing only; the per-visitor journey (`/visitors/detail`) is the\nconsent-gated drill-in.","operationId":"listAnalyticsVisitors","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorsListRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CursorPaginatedResponse_VisitorSummaryItem_"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/analytics/visitors/detail":{"post":{"tags":["analytics"],"summary":"Query Visitor Detail","description":"Get all page visits for one visitor, ordered chronologically.\n\nReturns individual beacons with URL, timestamp, navigation type, and\nperformance metrics for each page view.\n\nNeeds a per-visitor identifier: `identity=session` or `identity=stitch`\n(whichever the site collects — the caller passes the same identity the\nvisitor list used). A site collecting neither (the `minimal` posture) simply\nhas no visitors to drill into. Any other identity value is rejected with 422.","operationId":"getAnalyticsVisitorDetail","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorDetailRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VisitorDetailResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/synthetic/pages":{"get":{"tags":["synthetic"],"summary":"List Org Synthetic Pages","description":"List monitored pages across all sites of the org (manual first, then auto).\n\nOrg-scoped twin of `list_synthetic_pages`: `SyntheticPage` has no\n`organization_id`, so scope is resolved by joining `sites.organization_id`;\neach row still carries its own `site_id`. Optional `site_id` narrows to one\nsite. `summary=true` attaches the cached latest-result health snapshot per\npage (concurrency-capped), same as the site-scoped list.","operationId":"listOrgSyntheticPages","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"site_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Optional: restrict to one site","title":"Site Id"},"description":"Optional: restrict to one site"},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SyntheticPageSource"},{"type":"null"}],"description":"Filter by manual/auto","title":"Source"},"description":"Filter by manual/auto"},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"description":"Substring match on URL","title":"Q"},"description":"Substring match on URL"},{"name":"summary","in":"query","required":false,"schema":{"type":"boolean","description":"Attach the latest-result health summary per page","default":false,"title":"Summary"},"description":"Attach the latest-result health summary per page"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_SyntheticPageListItem_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/pages":{"post":{"tags":["synthetic"],"summary":"Create Synthetic Page","description":"Create a synthetic page (URL normalized + must be under the site domain).\n\nRegistering the CS site always kicks off exactly one immediate analysis — you\ncan't create a CS site without it running once — so even a paused page\n(`schedule=false`) produces this one creation run; its `analysis_uuid` is returned\nso the client polls `analyses/{uuid}/status` instead of firing a redundant `run`.\n\n`mode=monitor` (default) is a sticky, quota-counted page honoring the schedule\nflags. `mode=oneshot` is an unbudgeted \"measure now\": schedules forced off,\n`nocache` forced true, and a missing creation-run id is fatal (502) rather than\ntolerated — the run *is* the deliverable. A one-shot stays viewable via the normal\ndetail/run endpoints and can be promoted later via PATCH (source→manual + schedule).\n\nOne-shot is intentionally **unbounded** (no quota) — note the cost: CS has no\nreliable teardown, so each one-shot on a *new* URL leaves a CS site we can't reap.\nAdd a cap here once CS supports teardown.","operationId":"createSyntheticPage","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticPageCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticPageCreateResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Conflict - Resource already exists or operation not allowed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"get":{"tags":["synthetic"],"summary":"List Synthetic Pages","description":"List monitored pages (manual first, then auto by rank). Paginated + filterable.\nWith `summary=true`, each row carries its latest-result score/last-run (one\nbackend call per page, cached) — avoids the client doing N result calls.","operationId":"listSyntheticPages","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"source","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/SyntheticPageSource"},{"type":"null"}],"description":"Filter by manual/auto","title":"Source"},"description":"Filter by manual/auto"},{"name":"q","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"description":"Substring match on URL","title":"Q"},"description":"Substring match on URL"},{"name":"summary","in":"query","required":false,"schema":{"type":"boolean","description":"Attach the latest-result health summary per page","default":false,"title":"Summary"},"description":"Attach the latest-result health summary per page"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_SyntheticPageListItem_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/summary":{"get":{"tags":["synthetic"],"summary":"Get Synthetic Summary","description":"Site-wide overview: a per-page sparkline (recent per-run scores + run count)\nplus the aggregate latest score across pages and total run count.\n\nBuilt live from the 1h-cached per-page series — no stored aggregate, so CS stays\nthe single source of truth. Concurrency-capped like the list summary.","operationId":"getSyntheticSummary","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticSummaryResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/auto/refresh":{"post":{"tags":["synthetic"],"summary":"Refresh Auto Pages","description":"Populate auto pages from the site's Top-N RUM URLs (additive in v1).","operationId":"refreshSyntheticAutoPages","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SyntheticPageResponse"},"title":"Response Refreshsyntheticautopages"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/pages/{page_id}":{"patch":{"tags":["synthetic"],"summary":"Update Synthetic Page","description":"Update monitoring config: `schedule`, `ttfb_schedule`, `nocache`.\n\nTurning a schedule off pushes the new schedule state to CS; `schedule=false`\npauses the recurring Lighthouse run (the page stays and is still runnable on\ndemand). Turning it back on restores the recurring run. `nocache` toggles CS\ncache-bypass for the page's future runs (it is persisted and applied on the\nnext trigger; a `nocache`-only change does not itself fire a new CS run).","operationId":"updateSyntheticPage","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticPageUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticPageResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["synthetic"],"summary":"Delete Synthetic Page","description":"Delete a monitored page. Tears down the CS site (stops its schedules) via\nthe provider's delete endpoint; if that call fails the local page is still\nremoved and the CS site is flagged cs_orphan for later reconciliation.","operationId":"deleteSyntheticPage","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/pages/{page_id}/run":{"post":{"tags":["synthetic"],"summary":"Run Synthetic Page","description":"Trigger an on-demand analysis (the run completes asynchronously at CS).\n\nAlways allowed for an existing page — a paused page (`schedule=false`) can still\nbe run on demand; the page's recurring schedules are preserved on the rerun.\nUses the page's `nocache` setting unless the `nocache` query param overrides it\nfor this single run.","operationId":"runSyntheticPage","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"nocache","in":"query","required":false,"schema":{"anyOf":[{"type":"boolean"},{"type":"null"}],"description":"Override cache-busting for this run; omit to use the page's `nocache` setting. true = bust the page's CDN cache (fresh origin fetch), false = measure with normal CDN caching.","title":"Nocache"},"description":"Override cache-busting for this run; omit to use the page's `nocache` setting. true = bust the page's CDN cache (fresh origin fetch), false = measure with normal CDN caching."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticRunResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/pages/{page_id}/analyses/{analysis_uuid}/status":{"get":{"tags":["synthetic"],"summary":"Get Synthetic Analysis Status","description":"Progress of an in-flight analysis (for run UX). Not cached — status changes\nwhile the run is in progress.\n\nWhen the run reports done, we drop the page's 1h overview caches (sparkline +\nlatest summary) so the just-finished run shows up immediately — our only\ninvalidation signal, since CS has no completion webhook.","operationId":"getSyntheticAnalysisStatus","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"analysis_uuid","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Analysis Uuid"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticAnalysisStatus"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/pages/{page_id}/results":{"get":{"tags":["synthetic"],"summary":"List Synthetic Results","description":"Fetch synthetic-monitoring result history for a page, shaped to our\nasset-free schema.","operationId":"listSyntheticResults","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"result_type","in":"query","required":false,"schema":{"type":"string","pattern":"^(cs|ttfb|all)$","default":"cs","title":"Result Type"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":10,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticResultsResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/pages/{page_id}/runs":{"get":{"tags":["synthetic"],"summary":"List Synthetic Runs","description":"Lightweight run list backing the run-selector: per-run id + timestamp +\nper-device score only — no scores[]/ttfb/curation, so the selector payload stays\nsmall. Fetched live from CS (the system of record); pick a run, then use its\n`analysis_uuid` on the detail endpoints.","operationId":"listSyntheticRuns","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":20,"title":"Limit"}},{"name":"from","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 lower bound","title":"From"},"description":"ISO 8601 lower bound"},{"name":"to","in":"query","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"description":"ISO 8601 upper bound","title":"To"},"description":"ISO 8601 upper bound"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SyntheticRunsResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/sites/{site_id}/synthetic/pages/{page_id}/lab-vs-field":{"get":{"tags":["synthetic"],"summary":"Get Lab Vs Field","description":"Compare a CS lab run against RUM field p75, per device. The comparison axis is\nthe lab-measurable CWV (LCP/FCP/CLS/TTFB); INP is field-only (shown beside the lab\nTBT proxy). Also returns the CS lab CommerceScore and our field Experience Score\nside by side. Latest run unless `analysis_uuid` given; field reflects `window_days`.","operationId":"getSyntheticLabVsField","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"window_days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":7,"title":"Window Days"}},{"name":"analysis_uuid","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Target a specific run; default latest","title":"Analysis Uuid"},"description":"Target a specific run; default latest"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LabVsFieldResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/pages/{page_id}/ttfb":{"get":{"tags":["synthetic"],"summary":"Get Synthetic Ttfb","description":"Diagnose TTFB: CS server-side phase breakdown vs RUM field p75, classifying\nserver-bound vs network/geo-bound. CS phases are per-page; field p75 per device.\nLatest run unless `analysis_uuid` given.","operationId":"getSyntheticTtfb","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"window_days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":7,"title":"Window Days"}},{"name":"analysis_uuid","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Target a specific run; default latest","title":"Analysis Uuid"},"description":"Target a specific run; default latest"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TtfbDiagnosisResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/pages/{page_id}/timeseries":{"get":{"tags":["synthetic"],"summary":"Get Synthetic Timeseries","description":"Chart series for the device: sparse `lab` points (one per CS Lighthouse run,\nscore + CWV from that run's scores[]) and raw `ttfb` points (one per dedicated\n5-min TTFB run, full DNS→transfer phases) overlaid on the regular `field` p75 line\n(RUM). `lab.ttfb` is Lighthouse's server-only TTFB; the `ttfb` series is the full\nphase breakdown — different measurements, kept in separate series. The `ttfb`\nseries is device-independent (CS measures TTFB once per run).\n\n`series` selects which to compute — only the requested ones are fetched; the rest\nreturn as empty lists.","operationId":"getSyntheticTimeseries","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"device","in":"query","required":false,"schema":{"type":"string","pattern":"^(desktop|mobile)$","default":"desktop","title":"Device"}},{"name":"window_days","in":"query","required":false,"schema":{"type":"integer","maximum":90,"minimum":1,"default":30,"title":"Window Days"}},{"name":"interval","in":"query","required":false,"schema":{"type":"string","pattern":"^(hour|day)$","default":"day","title":"Interval"}},{"name":"series","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated subset of lab,ttfb,field to compute. Unrequested series come back empty; use it to skip the expensive TTFB pull when unneeded. An empty/blank value means all series.","default":"lab,ttfb,field","title":"Series"},"description":"Comma-separated subset of lab,ttfb,field to compute. Unrequested series come back empty; use it to skip the expensive TTFB pull when unneeded. An empty/blank value means all series."}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimeseriesResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/pages/{page_id}/lighthouse":{"get":{"tags":["synthetic"],"summary":"Get Synthetic Lighthouse","description":"Curated Lighthouse report (latest run unless `analysis_uuid` given): category\nscores, metrics, opportunities, and native LH audit objects for waterfall /\nthird-party /\nresource-summary / filmstrip / main-thread).","operationId":"getSyntheticLighthouse","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"device","in":"query","required":false,"schema":{"type":"string","pattern":"^(desktop|mobile)$","default":"desktop","title":"Device"}},{"name":"analysis_uuid","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Target a specific run; default latest","title":"Analysis Uuid"},"description":"Target a specific run; default latest"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LighthouseReportResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/pages/{page_id}/lighthouse/raw":{"get":{"tags":["synthetic"],"summary":"Get Synthetic Lighthouse Raw","description":"The complete, unshaped Lighthouse report for a run + device (~250KB; latest\nunless `analysis_uuid` given). Use the smaller `/lighthouse` unless you need it.","operationId":"getSyntheticLighthouseRaw","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"device","in":"query","required":false,"schema":{"type":"string","pattern":"^(desktop|mobile)$","default":"desktop","title":"Device"}},{"name":"analysis_uuid","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Target a specific run; default latest","title":"Analysis Uuid"},"description":"Target a specific run; default latest"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"title":"Response Getsyntheticlighthouseraw"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/sites/{site_id}/synthetic/pages/{page_id}/lighthouse/summary":{"get":{"tags":["synthetic"],"summary":"Get Stored Lighthouse Summary","description":"Read-only: the stored AI summary for a run (latest unless `analysis_uuid`), or\n**404** if none has been generated yet. NEVER generates — no LLM call, no rate-limit\ncost — so the UI can decide between a \"View\" and a \"Generate\" affordance without\ntriggering (and paying for) generation. Use `POST` to actually generate.\n\nRun resolution is the same domain-guarded, cached path the other Lighthouse routes\nuse (so a foreign `analysis_uuid` can't be read); only the LLM work is skipped.","operationId":"getStoredSyntheticLighthouseSummary","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"device","in":"query","required":false,"schema":{"type":"string","pattern":"^(desktop|mobile)$","default":"desktop","title":"Device"}},{"name":"language","in":"query","required":false,"schema":{"type":"string","pattern":"^(en|de)$","default":"en","title":"Language"}},{"name":"analysis_uuid","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Target a specific run; default latest","title":"Analysis Uuid"},"description":"Target a specific run; default latest"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LighthouseSummaryResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["synthetic"],"summary":"Get Synthetic Lighthouse Summary","description":"An AI summary of a page's Lighthouse run (latest unless `analysis_uuid`).\n\nGenerated once per (run, device): English first, then translated to German, and\n**both stored** in `lighthouse_summaries` — a completed run is immutable, so repeat\nrequests are served from the DB (`cached=true`) at no LLM cost. Requires the org's\nAI to be enabled (`require_ai_enabled`).","operationId":"getSyntheticLighthouseSummary","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"page_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Page Id"}},{"name":"site_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Site Id"}},{"name":"device","in":"query","required":false,"schema":{"type":"string","pattern":"^(desktop|mobile)$","default":"desktop","title":"Device"}},{"name":"language","in":"query","required":false,"schema":{"type":"string","pattern":"^(en|de)$","default":"en","title":"Language"}},{"name":"analysis_uuid","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"Target a specific run; default latest","title":"Analysis Uuid"},"description":"Target a specific run; default latest"}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LighthouseSummaryResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/issues":{"get":{"tags":["issues"],"summary":"List Issues","operationId":"list_issues_v1_organizations__org_id__issues_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"status","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/IssueStatus"},{"type":"null"}],"title":"Status"}},{"name":"category","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/IssueCategory"},{"type":"null"}],"title":"Category"}},{"name":"severity","in":"query","required":false,"schema":{"anyOf":[{"$ref":"#/components/schemas/IssueSeverity"},{"type":"null"}],"title":"Severity"}},{"name":"application_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Application Id"}},{"name":"site_id","in":"query","required":false,"schema":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Site Id"}},{"name":"include_shadow","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Shadow"}},{"name":"include_stats","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Stats"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_IssueResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/issues/{issue_id}":{"get":{"tags":["issues"],"summary":"Get Issue","operationId":"get_issue_v1_issues__issue_id__get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"issue_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Issue Id"}},{"name":"include_stats","in":"query","required":false,"schema":{"type":"boolean","default":false,"title":"Include Stats"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueDetailResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["issues"],"summary":"Update Issue","description":"Triage: resolve, reopen, or mute.\n\nEvery transition writes an `issue_event` with the acting user. That audit\ntrail is not decoration: the plan's precision-feedback loop (§7d) reads mute\nand quick-resolve actions as the false-positive proxy signal used to\nrecalibrate detectors, so losing the actor or the timing loses the metric.","operationId":"update_issue_v1_issues__issue_id__patch","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"issue_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Issue Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueResponse"}}}},"400":{"description":"Bad Request - Invalid input","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/issues/{issue_id}/comment":{"post":{"tags":["issues"],"summary":"Comment Issue","operationId":"comment_issue_v1_issues__issue_id__comment_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"issue_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Issue Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueComment"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueEventResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/notifications/metadata":{"get":{"tags":["notifications"],"summary":"List notification rule inputs","description":"List every metric, aggregation, dimension and allowed window size that\na notification rule can reference. Drives the metric picker and the window\ndropdown in the rule editor UI.","operationId":"getNotificationMetadata","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetadataResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/notifications/presets":{"get":{"tags":["notifications"],"summary":"List rule templates","description":"Return the set of ready-made rule templates (LCP regression, error\nspike, traffic drop, etc.). Used as the starting point in the new-rule\nflow: the client pre-fills the editor from the chosen preset and the\nuser only fills in scope + recipients.","operationId":"listNotificationPresets","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PresetResponse"},"title":"Response Listnotificationpresets"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/notifications/rules":{"get":{"tags":["notifications"],"summary":"List notification rules","description":"List every notification rule in the organization, with their configured\nactions nested. Action secrets (webhook HMAC key, Slack / Discord URLs)\nare masked in the response; users rotate them by re-entering new values\non edit.","operationId":"listNotificationRules","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_RuleResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["notifications"],"summary":"Create a notification rule","description":"Create a new rule together with its actions in a single call. The\nscope target (site or tag) is validated against the org. Requires org\nowner role.","operationId":"createNotificationRule","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/organizations/{org_id}/notifications/preview":{"post":{"tags":["notifications"],"summary":"Historical preview of a rule shape","description":"Replay a rule shape (which may or may not be saved yet) against the\nlast N days of data and return time-series buckets with threshold\nbreaches + the exact number of notifications the state machine would\nhave emitted.\n\nPowers the chart in the rule editor: as the user tweaks metric,\naggregation, threshold, window, filters or the re-notify cadence, the\nclient re-calls this endpoint and re-renders the chart. Bucket size is\nalways equal to the rule's evaluation window so each bucket's value\nrepresents one real evaluation.","operationId":"previewNotificationRule","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacktestRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BacktestResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/notification-rules/{rule_id}":{"get":{"tags":["notifications"],"summary":"Get a rule","description":"Fetch a single rule by ID, with its actions. Action secrets are\nmasked on read; see `List notification rules`.","operationId":"getNotificationRule","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rule Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"patch":{"tags":["notifications"],"summary":"Update a rule","description":"Update mutable fields on an existing rule (name, threshold, window,\noperator, filters, re-notify cadence, enabled state). Scope and metric\nare fixed at creation; delete and recreate to change them.\n\nIf `actions` is included, the entire action list is replaced (existing\naction rows are deleted and re-inserted). Requires org owner role.","operationId":"updateNotificationRule","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rule Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleUpdate"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RuleResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error - Request validation failed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"delete":{"tags":["notifications"],"summary":"Delete a rule","description":"Delete a rule. Cascades to its actions, per-site firing state, and\nsend history. Cannot be undone. Requires org owner role.","operationId":"deleteNotificationRule","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rule Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/notification-rules/{rule_id}/test":{"post":{"tags":["notifications"],"summary":"Send a synthetic test notification","description":"Send a synthetic notification through every active action of this rule,\nusing fake values for the template variables (so you can verify that\nemail delivery, webhook signing, Slack formatting etc. all work end to\nend). Nothing about the rule's firing state changes; no `send` row is\nrecorded. Requires org owner role.","operationId":"testNotificationRule","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rule Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TestSendResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/notification-rules/{rule_id}/evaluate":{"post":{"tags":["notifications"],"summary":"Evaluate now (dry-run)","description":"Run a single dry-run of the rule against live analytics data and\nreturn the observed value per site plus whether the condition is currently\nsatisfied. No notification is dispatched and no state is written; useful\nfor answering \"would this fire right now?\" without waiting for the worker\nor changing anything.","operationId":"evaluateNotificationRule","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rule Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EvaluateResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/notification-rules/{rule_id}/sends":{"get":{"tags":["notifications"],"summary":"Notification history for a rule","description":"Paginated history of notifications actually sent for this rule, newest\nfirst. Each row includes the metric value at fire time, the full context\nsnapshot that was rendered into the notification, and the per-action\ndelivery log (status, delivered / failed counts, error messages).\n\nThis is what powers the \"History\" tab in the rule detail dialog.","operationId":"listNotificationSends","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"rule_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Rule Id"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_SendResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/partner/clients":{"get":{"tags":["partners"],"summary":"List Clients","description":"List client organizations managed by this partner org.","operationId":"listPartnerClients","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":50,"title":"Limit"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaginatedResponse_PartnerClientResponse_"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"post":{"tags":["partners"],"summary":"Create Client","description":"Create a brand-new organization and link it to this partner as a client.\n\nRequires owner-level *direct* membership of the partner org (partner access\ncan't escalate to owner), and the org must carry the partner entitlement\n(`is_partner`).\n\nUnlike `POST /admin/partners` (which links an existing org and is admin-only),\nthis lets a partner self-provision client orgs. By default the new org gets\n**no direct member** — it is managed through partner access until a real\ncustomer takes ownership. Pass `owner_email` to invite that customer as OWNER\nin the same step (an invite email is sent; on accept they become owner).","operationId":"createPartnerClient","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerClientCreate"}}}},"responses":{"201":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerClientResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/partner/clients/{client_org_id}":{"delete":{"tags":["partners"],"summary":"Remove Client","description":"Detach a client org from this partner — and delete it if orphaned.\n\nOwner-level direct membership of the partner org is required. Only links\nowned by *this* partner org can be removed (you can't detach another\npartner's client).\n\nIf, after detaching, the client org has no members and no other partner\nlinks, it is unreachable by anyone and gets fully deleted (sites, invites,\nmemberships) — mirroring the \"last member leaves → org is removed\"\nlifecycle. If the client still has members (a real customer was onboarded)\nor other partners, it survives; only this link is removed.","operationId":"removePartnerClient","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"client_org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Client Org Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/partner/usage":{"get":{"tags":["partners"],"summary":"Get Partner Usage","description":"Get aggregated beacon usage across all client organizations.","operationId":"getPartnerUsage","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PartnerUsageResponse"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/partner-access":{"get":{"tags":["partners"],"summary":"List Partner Access","description":"List the partner organizations that have access to this org.\n\nThe client's view of the `partners` relationship: shows whether — and which —\npartner org manages this org (empty list = none). Requires *direct*\nmembership, so a partner inspecting a client via partner access can't use\nthis to enumerate the client's relationships.","operationId":"listPartnerAccess","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/PartnerAccessResponse"},"title":"Response Listpartneraccess"}}}},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/organizations/{org_id}/partner-access/{partner_org_id}":{"delete":{"tags":["partners"],"summary":"Revoke Partner Access","description":"Revoke a partner organization's access to this (client) org.\n\nThe mirror of `DELETE /partner/clients/{client_org_id}`, but initiated by the\n*client*. `OrgOwner` requires direct owner-level membership of this org, which\nmeans a partner can't use its own partner access to revoke itself, and the\nacting owner always remains — so this call never orphans the org (no cascade\ndelete, unlike the partner-side removal).","operationId":"revokePartnerAccess","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Org Id"}},{"name":"partner_org_id","in":"path","required":true,"schema":{"type":"string","format":"uuid","title":"Partner Org Id"}}],"responses":{"204":{"description":"Successful Response"},"401":{"description":"Unauthorized - Invalid or missing authorization token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden - Insufficient permissions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not Found - Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal Server Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/c/{collector_hash}":{"get":{"tags":["collector"],"summary":"Collect Pixel","description":"Collect beacon via 1x1 pixel (GET).\n\nThis is the third fallback in the tracker's delivery chain, after\nsendBeacon (unload paths) and fetch keepalive POST (live paths). It\nfires when fetch() rejects, which most commonly happens when the\nrenderer is torn down between an OPTIONS preflight response and the\nPOST going out. Since v1.4.2 the live fetch path uses Content-Type\ntext/plain and no custom headers, so it never preflights and this\nfallback should be rare; we still accept it for ad-blocker-bypass\ncontexts and ancient browsers without fetch.\n\nIdentity (pvid/ver/lifecycle) is forwarded so the row collapses against\nany successfully-delivered POST for the same pageview via\nReplacingMergeTree(version).","operationId":"collect_pixel_c__collector_hash__get","parameters":[{"name":"collector_hash","in":"path","required":true,"schema":{"type":"string","title":"Collector Hash"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"ActionCreate":{"properties":{"type":{"$ref":"#/components/schemas/ActionType"},"is_active":{"type":"boolean","title":"Is Active","default":true},"config":{"additionalProperties":true,"type":"object","title":"Config"}},"type":"object","required":["type","config"],"title":"ActionCreate"},"ActionResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"type":{"$ref":"#/components/schemas/ActionType"},"is_active":{"type":"boolean","title":"Is Active"},"config":{"additionalProperties":true,"type":"object","title":"Config"}},"type":"object","required":["id","type","is_active","config"],"title":"ActionResponse","description":"Always-masked read representation.\n\nSecrets (webhook HMAC key, Slack/Discord webhook URLs) are never echoed in\nfull. If a user needs to rotate them, they re-enter the new value on edit."},"ActionType":{"type":"string","enum":["email","webhook","slack","discord"],"title":"ActionType"},"ActionUpdate":{"properties":{"type":{"$ref":"#/components/schemas/ActionType"},"is_active":{"type":"boolean","title":"Is Active","default":true},"config":{"additionalProperties":true,"type":"object","title":"Config"}},"type":"object","required":["type","config"],"title":"ActionUpdate"},"AggregationType":{"type":"string","enum":["count","avg","sum","min","max","p50","p75","p90","p95","p99"],"title":"AggregationType","description":"Supported aggregation functions."},"AnalyticsDataPoint":{"properties":{"timestamp":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Timestamp","description":"Timestamp (present when grouping by time)"},"dimensions":{"additionalProperties":{"type":"string"},"type":"object","title":"Dimensions","description":"Dimension values for this data point"},"metrics":{"items":{"$ref":"#/components/schemas/MetricValue"},"type":"array","title":"Metrics","description":"Metric values"},"beacons":{"type":"integer","title":"Beacons","description":"Number of beacons in this bucket"},"comparison":{"anyOf":[{"$ref":"#/components/schemas/ComparisonData"},{"type":"null"}],"description":"Comparison data (when compare_to is set)"}},"type":"object","required":["metrics","beacons"],"title":"AnalyticsDataPoint","description":"Single data point in query results."},"AnalyticsQueryMeta":{"properties":{"total_rows":{"type":"integer","title":"Total Rows","description":"Total rows matching the query"},"returned_rows":{"type":"integer","title":"Returned Rows","description":"Number of rows returned"},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time in milliseconds"},"query_hash":{"type":"string","title":"Query Hash","description":"Hash for debugging/caching reference"},"time_range":{"additionalProperties":true,"type":"object","title":"Time Range","description":"Applied time range"},"comparison_time_range":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Comparison Time Range","description":"Comparison time range (when compare_to is set)"},"applied_filters":{"additionalProperties":true,"type":"object","title":"Applied Filters","description":"Applied filter values"}},"type":"object","required":["total_rows","returned_rows","execution_time_ms","query_hash","time_range","applied_filters"],"title":"AnalyticsQueryMeta","description":"Metadata about the query execution."},"AnalyticsQueryRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query (required)"},"metrics":{"items":{"anyOf":[{"type":"string"},{"$ref":"#/components/schemas/MapMetric"}]},"type":"array","maxItems":10,"minItems":1,"title":"Metrics","description":"Metrics to query. Strings for flat or Nested (errors.count) metrics; objects for Map-key access (e.g. resource_sizes['script']). Cache-status rates follow the pattern `(cdn|origin)_status_rate_<status>` (lowercase, e.g. cdn_status_rate_miss; `unreported` = no status sent) — AVG-only ratio 0–1 over all pageviews. `cdn_hit_rate`/`origin_hit_rate` are legacy aliases for `*_status_rate_hit`."},"aggregations":{"items":{"$ref":"#/components/schemas/AggregationType"},"type":"array","maxItems":7,"minItems":1,"title":"Aggregations","description":"Aggregation functions to apply","default":["p75"]},"group_by":{"$ref":"#/components/schemas/GroupBy","description":"Grouping configuration (time and/or dimensions)"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"compare_to":{"anyOf":[{"$ref":"#/components/schemas/CompareMode"},{"type":"null"}],"description":"Compare to previous time period"},"compare_to_release_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Compare To Release Id","description":"Compare metrics before vs after a specific release"},"limit":{"type":"integer","maximum":10000.0,"minimum":1.0,"title":"Limit","description":"Maximum rows to return","default":2500},"offset":{"type":"integer","minimum":0.0,"title":"Offset","description":"Offset for pagination","default":0},"order_by":{"anyOf":[{"$ref":"#/components/schemas/OrderBy"},{"type":"null"}],"description":"Sort configuration"},"identity":{"anyOf":[{"type":"string","enum":["stitch","session"]},{"type":"null"}],"title":"Identity","description":"Backing identifier for the `visitors` metric: 'stitch' (preferred — edge-derived, present under ANONYMOUS) or 'session' (consent-gated session_id). Null resolves to the per-site default (stitch unless the site only collects sessions). Ignored by all other metrics."}},"additionalProperties":false,"type":"object","required":["time_range","metrics"],"title":"AnalyticsQueryRequest","description":"Main request schema for analytics queries."},"AnalyticsQueryResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/AnalyticsDataPoint"},"type":"array","title":"Data","description":"Query result data points"},"meta":{"$ref":"#/components/schemas/AnalyticsQueryMeta","description":"Query metadata"}},"type":"object","required":["data","meta"],"title":"AnalyticsQueryResponse","description":"Response for analytics queries."},"ApplicationCreate":{"properties":{"name":{"type":"string","maxLength":255,"title":"Name","default":"Default"},"environment":{"$ref":"#/components/schemas/Environment","default":"prod"},"data_retention_days":{"type":"integer","title":"Data Retention Days","default":90},"store_stitch":{"type":"boolean","title":"Store Stitch","default":false},"count_visitors_by":{"$ref":"#/components/schemas/VisitorIdentity","default":"stitch"},"site_policy":{"$ref":"#/components/schemas/SitePolicy","default":"open"},"collect_sessions":{"type":"boolean","title":"Collect Sessions","default":false},"collect_fetch_xhr":{"type":"boolean","title":"Collect Fetch Xhr","default":false},"session_consent":{"$ref":"#/components/schemas/SessionConsent","default":"deferred"},"collect_error_messages":{"type":"boolean","title":"Collect Error Messages","default":false},"collect_error_frames":{"type":"boolean","title":"Collect Error Frames","default":false},"collect_query_keys":{"type":"boolean","title":"Collect Query Keys","default":false},"collect_query_values_for":{"items":{"type":"string"},"type":"array","maxItems":20,"title":"Collect Query Values For"},"pagetype_ruleset":{"type":"string","title":"Pagetype Ruleset","default":""},"preset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Preset"},"collector_mode":{"$ref":"#/components/schemas/CollectorMode","default":"default"},"collector_endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Collector Endpoint"},"source_version":{"type":"string","maxLength":20,"title":"Source Version","default":"v1"}},"type":"object","title":"ApplicationCreate","description":"Provision an application (a tracking embed). The collection config applies\nto every domain the app is embedded on. data_retention_days / store_stitch /\ncount_visitors_by are the per-domain DEFAULTS its member sites inherit (a site\ncan override)."},"ApplicationResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"organization_id":{"type":"string","format":"uuid","title":"Organization Id"},"name":{"type":"string","title":"Name"},"environment":{"$ref":"#/components/schemas/Environment"},"data_retention_days":{"type":"integer","title":"Data Retention Days"},"store_stitch":{"type":"boolean","title":"Store Stitch"},"count_visitors_by":{"$ref":"#/components/schemas/VisitorIdentity"},"site_policy":{"$ref":"#/components/schemas/SitePolicy"},"source_hash":{"type":"string","title":"Source Hash"},"collector_hash":{"type":"string","title":"Collector Hash"},"collect_sessions":{"type":"boolean","title":"Collect Sessions"},"collect_fetch_xhr":{"type":"boolean","title":"Collect Fetch Xhr"},"session_consent":{"$ref":"#/components/schemas/SessionConsent"},"collect_error_messages":{"type":"boolean","title":"Collect Error Messages"},"collect_error_frames":{"type":"boolean","title":"Collect Error Frames"},"collect_query_keys":{"type":"boolean","title":"Collect Query Keys"},"collect_query_values_for":{"items":{"type":"string"},"type":"array","title":"Collect Query Values For","default":[]},"pagetype_ruleset":{"type":"string","title":"Pagetype Ruleset","default":""},"collector_mode":{"$ref":"#/components/schemas/CollectorMode"},"collector_endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Collector Endpoint"},"source_version":{"type":"string","title":"Source Version"},"is_active":{"type":"boolean","title":"Is Active"},"site_count":{"type":"integer","title":"Site Count","default":0},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","organization_id","name","environment","data_retention_days","store_stitch","count_visitors_by","site_policy","source_hash","collector_hash","collect_sessions","collect_fetch_xhr","session_consent","collect_error_messages","collect_error_frames","collect_query_keys","collector_mode","collector_endpoint","source_version","is_active","created_at","updated_at"],"title":"ApplicationResponse"},"ApplicationSiteCreate":{"properties":{"domain":{"type":"string","title":"Domain"},"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"}},"type":"object","required":["domain"],"title":"ApplicationSiteCreate","description":"Adopt a domain into an application as a child site.\n\nDeliberately minimal: the collection config is the application's, applied at\ningest, so only the domain (and an optional display name) are needed. The\ncreated site carries NO own embed — it is served/collected via the\napplication's. Typically called with a hostname from the discovery list."},"ApplicationUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Name"},"environment":{"anyOf":[{"$ref":"#/components/schemas/Environment"},{"type":"null"}]},"data_retention_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Data Retention Days"},"store_stitch":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Store Stitch"},"count_visitors_by":{"anyOf":[{"$ref":"#/components/schemas/VisitorIdentity"},{"type":"null"}]},"site_policy":{"anyOf":[{"$ref":"#/components/schemas/SitePolicy"},{"type":"null"}]},"collect_sessions":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Collect Sessions"},"collect_fetch_xhr":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Collect Fetch Xhr"},"session_consent":{"anyOf":[{"$ref":"#/components/schemas/SessionConsent"},{"type":"null"}]},"collect_error_messages":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Collect Error Messages"},"collect_error_frames":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Collect Error Frames"},"collect_query_keys":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Collect Query Keys"},"collect_query_values_for":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":20},{"type":"null"}],"title":"Collect Query Values For"},"pagetype_ruleset":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pagetype Ruleset"},"collector_mode":{"anyOf":[{"$ref":"#/components/schemas/CollectorMode"},{"type":"null"}]},"collector_endpoint":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Collector Endpoint"},"source_version":{"anyOf":[{"type":"string","maxLength":20},{"type":"null"}],"title":"Source Version"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"}},"type":"object","title":"ApplicationUpdate"},"AuditAction":{"type":"string","enum":["org.created","org.deleted","org.consent_changed","org.plan_changed","org.partner_changed","org.approval_changed","org.ownership_transferred","org.member_added","org.member_removed","partner.added","partner.removed","site.created","site.updated","site.deleted","site.hashes_rotated","org_tracker.created","org_tracker.updated","org_tracker.deleted","org_tracker.hashes_rotated","org_tracker.site_assigned","org_tracker.site_unassigned","synthetic_page.created","synthetic_page.updated","synthetic_page.deleted","api_key.regenerated","app_token.issued","app_token.revoked","passkey.registered","passkey.removed"],"title":"AuditAction","description":"Audited actions. Extend as more events become worth recording."},"AuditLogEntry":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"action":{"$ref":"#/components/schemas/AuditAction"},"actor_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor User Id"},"actor_email":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Actor Email"},"target_type":{"anyOf":[{"$ref":"#/components/schemas/AuditTargetType"},{"type":"null"}]},"target_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Target Id"},"meta":{"additionalProperties":true,"type":"object","title":"Meta"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","action","actor_user_id","actor_email","target_type","target_id","meta","created_at"],"title":"AuditLogEntry","description":"One recorded change in the audit trail."},"AuditTargetType":{"type":"string","enum":["organization","site","org_tracker","synthetic_page","user","partner","app_token","passkey"],"title":"AuditTargetType"},"BacktestBucket":{"properties":{"ts":{"type":"string","format":"date-time","title":"Ts"},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value"},"is_breach":{"type":"boolean","title":"Is Breach"},"is_fire":{"type":"boolean","title":"Is Fire","default":false}},"type":"object","required":["ts","value","is_breach"],"title":"BacktestBucket"},"BacktestRequest":{"properties":{"scope_type":{"$ref":"#/components/schemas/ScopeType"},"site_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Site Id"},"tag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"},"metric":{"type":"string","title":"Metric"},"aggregation":{"type":"string","title":"Aggregation"},"identity":{"anyOf":[{"type":"string","enum":["stitch","session"]},{"type":"null"}],"title":"Identity"},"operator":{"$ref":"#/components/schemas/Operator"},"condition_type":{"$ref":"#/components/schemas/ConditionType"},"threshold":{"type":"number","title":"Threshold"},"window_seconds":{"type":"integer","title":"Window Seconds"},"baseline_window_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Baseline Window Seconds"},"filters":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Filters"},"range_days":{"anyOf":[{"type":"integer","maximum":365.0,"minimum":1.0},{"type":"null"}],"title":"Range Days"},"re_notify_after_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Re Notify After Seconds"}},"type":"object","required":["scope_type","metric","aggregation","operator","condition_type","threshold","window_seconds"],"title":"BacktestRequest","description":"The rule shape to evaluate historically. No id; rule may not yet exist."},"BacktestResponse":{"properties":{"buckets":{"items":{"$ref":"#/components/schemas/BacktestBucket"},"type":"array","title":"Buckets"},"breach_count":{"type":"integer","title":"Breach Count"},"fire_count":{"type":"integer","title":"Fire Count"},"unit":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Unit"},"granularity":{"type":"string","title":"Granularity"},"range_days":{"type":"integer","title":"Range Days"}},"type":"object","required":["buckets","breach_count","fire_count","unit","granularity","range_days"],"title":"BacktestResponse"},"BeaconBreakdownsRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"}},"additionalProperties":false,"type":"object","required":["time_range"],"title":"BeaconBreakdownsRequest","description":"Request for the orthogonal beacon-ingestion breakdowns."},"BeaconBreakdownsResponse":{"properties":{"total_count":{"type":"integer","title":"Total Count"},"collection_mode":{"additionalProperties":{"type":"integer"},"type":"object","title":"Collection Mode"},"delivery_method":{"additionalProperties":{"type":"integer"},"type":"object","title":"Delivery Method"},"lifecycle":{"additionalProperties":{"type":"integer"},"type":"object","title":"Lifecycle"},"tracker_version":{"additionalProperties":{"type":"integer"},"type":"object","title":"Tracker Version"}},"type":"object","required":["total_count","collection_mode","delivery_method","lifecycle","tracker_version"],"title":"BeaconBreakdownsResponse","description":"Response with orthogonal beacon-count breakdowns across the\ningestion-side dimensions of the same row set.\n\nThe first three maps are fixed-enum and each sums to `total_count`;\n`tracker_version` is open-valued and capped at the top-20:\n\n- `collection_mode`: privacy class. Inferred from `session_id`: non-empty\n  means the beacon was collected in full mode (consent given or site set\n  to FULL), empty means anonymous.\n- `delivery_method`: transport channel. Server-classified at ingest from\n  request shape + tracker marker (see migration 024).\n- `lifecycle`: pageview-lifecycle stage when the beacon was emitted\n  (init / loaded / hidden / ...). Useful to gauge how often pageviews\n  reach the loaded state vs. bounce before LCP.\n- `tracker_version`: top tracker bundles by beacon volume, format\n  `YYMMDD-<git-sha>[-dirty]`. Open value space (one per build), so\n  capped at the top-20 by count to bound response size. Lets you watch\n  cache-rollover progress and spot stale builds. Empty string covers\n  legacy beacons (pre-stamp migration) and the static `<noscript>`\n  pixel which has no runtime to stamp.\n\nMaps over flat `*_count` fields so new values (additional delivery\nchannels, future lifecycle stages, new tracker builds) flow through\nwithout a schema change on either side. Frontend computes percentages\nfrom `count / total_count`."},"BeaconError":{"properties":{"fingerprint":{"type":"string","title":"Fingerprint","description":"Stable group-by key for this error signature."},"type":{"type":"string","title":"Type","description":"Error class name, e.g. TypeError, ResourceLoadError"},"is_first_party":{"type":"boolean","title":"Is First Party","description":"True if any captured frame's host equals the page host."},"count":{"type":"integer","title":"Count","description":"Occurrences of this signature on this beacon"},"sample_message":{"type":"string","title":"Sample Message","description":"Short PII-stripped message fingerprint (≤80 chars after sanitization)"},"frames":{"items":{"$ref":"#/components/schemas/ErrorFrameInfo"},"type":"array","title":"Frames","description":"Captured stack frames (max 5). frames[0] is the throw site."},"error_class":{"type":"string","title":"Error Class","description":"Classification (migration 048): '' = real error, 'blocked' = ad-blocked tracker request (a status-0 ResourceLoadError against a known tracker host, excluded from error_count).","default":""}},"type":"object","required":["fingerprint","type","is_first_party","count","sample_message"],"title":"BeaconError","description":"One bucketed error from a beacon's structured `errors` Nested column.\n\nServer-side projection of the parallel arrays (`errors.type`,\n`errors.frame_*`, `errors.fingerprint`, …) introduced in migration 010\nand extended to multi-frame in migration 017. The tracker emits up to\nfive entries per beacon, deduplicated locally by an internal hash key\nand capped via `errors.js`."},"BeaconFetchXhr":{"properties":{"method":{"type":"string","title":"Method","description":"HTTP method"},"host":{"type":"string","title":"Host","description":"Target host ('' = same-origin)"},"path":{"type":"string","title":"Path","description":"Templated path"},"calls":{"type":"integer","title":"Calls","description":"Calls to this endpoint on this pageview"},"sum_ms":{"type":"integer","title":"Sum Ms","description":"Total duration (ms)"},"max_ms":{"type":"integer","title":"Max Ms","description":"Slowest single call (ms)"},"errors":{"type":"integer","title":"Errors","description":"Errored calls (status >= 400 or network)"},"status_errors":{"additionalProperties":{"type":"integer"},"type":"object","title":"Status Errors","description":"Error-status distribution on this pageview (code → count)"},"duration_buckets":{"additionalProperties":{"type":"integer"},"type":"object","title":"Duration Buckets","description":"Latency histogram (bucket-upper-ms → count)"},"sync_calls":{"type":"integer","title":"Sync Calls","description":"Synchronous XHR (main-thread-blocking) calls","default":0},"aborts":{"type":"integer","title":"Aborts","description":"Aborted calls (user/navigation cancellation)","default":0},"blocked":{"type":"integer","title":"Blocked","description":"Ad-blocked status-0 calls to tracker hosts (not real failures)","default":0},"sum_bytes":{"type":"integer","title":"Sum Bytes","description":"Σ transferSize (same-origin/TAO; 0 masked)","default":0},"max_bytes":{"type":"integer","title":"Max Bytes","description":"Largest response (bytes); 0 masked","default":0},"sum_offset_ms":{"type":"integer","title":"Sum Offset Ms","description":"Σ start-offset from PV start (ms); sum_offset_ms/calls ≈ the endpoint's average waterfall position","default":0}},"type":"object","required":["method","host","path","calls","sum_ms","max_ms","errors"],"title":"BeaconFetchXhr","description":"One fetch_xhr endpoint this pageview called (from fetch_xhr_endpoints)."},"BeaconFetchXhrOutlier":{"properties":{"method":{"type":"string","title":"Method","description":"HTTP method"},"host":{"type":"string","title":"Host","description":"Target host ('' = same-origin)"},"path":{"type":"string","title":"Path","description":"Templated path"},"duration_ms":{"type":"integer","title":"Duration Ms","description":"Call duration (ms)"},"status":{"type":"integer","title":"Status","description":"HTTP status (0 = network error / unknown)"},"ttfb_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ttfb Ms","description":"TTFB (ms); null = cross-origin masked"},"server_timing":{"additionalProperties":{"type":"number"},"type":"object","title":"Server Timing","description":"The call's own backend phases (name → ms) from Server-Timing — same-origin/TAO only (empty cross-origin)."}},"type":"object","required":["method","host","path","duration_ms","status"],"title":"BeaconFetchXhrOutlier","description":"One slow fetch_xhr (>500 ms) captured on this pageview (fetch_xhr_outliers)."},"BeaconLoAF":{"properties":{"script_host":{"type":"string","title":"Script Host","description":"Attributed script host ('' = unattributed)"},"script_path":{"type":"string","title":"Script Path","description":"Attributed script path (origin-relative)"},"invoker_type":{"type":"string","title":"Invoker Type","description":"Invoker type (reserved; often '' on current tracker)","default":""},"total_ms":{"type":"integer","title":"Total Ms","description":"Total blocking time attributed to this script (ms)"},"frames":{"type":"integer","title":"Frames","description":"Number of long-animation-frame occurrences"}},"type":"object","required":["script_host","script_path","total_ms","frames"],"title":"BeaconLoAF","description":"One Long-Animation-Frame script attribution on this pageview (from the `loaf` Nested)."},"BeaconRow":{"properties":{"started_at":{"type":"string","format":"date-time","title":"Started At"},"ended_at":{"type":"string","format":"date-time","title":"Ended At"},"session_id":{"type":"string","title":"Session Id"},"stitch":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Stitch"},"pvid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Pvid"},"url":{"type":"string","title":"Url"},"site_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Site Id"},"version":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Version"},"tracker_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tracker Version"},"lifecycle":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lifecycle"},"delivery_method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Delivery Method"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"referrer_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Source"},"referrer_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Medium"},"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign"},"utm_term":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Term"},"utm_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Content"},"click_id_param":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Click Id Param"},"browser":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Browser"},"browser_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Browser Version"},"device_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Device Type"},"os":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Os"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"},"connection_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Connection Type"},"viewport_class":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Viewport Class"},"lcp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lcp"},"fcp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fcp"},"cls":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cls"},"inp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inp"},"tbt":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Tbt"},"ttfb":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ttfb"},"page_load_time":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Page Load Time"},"dom_interactive":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dom Interactive"},"start_render":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Start Render"},"content_transfer_duration":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Content Transfer Duration"},"dns_lookup":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Dns Lookup"},"tcp_connection":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Tcp Connection"},"total_byte_weight":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Byte Weight"},"cache_hit_rate":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cache Hit Rate"},"cached_resources":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Cached Resources"},"page_cached":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Page Cached"},"service_worker_active":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Service Worker Active"},"error_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Error Count"},"errors":{"items":{"$ref":"#/components/schemas/BeaconError"},"type":"array","title":"Errors","description":"Structured per-beacon errors (top 5 by occurrence). Sourced from the ClickHouse `errors` Nested column. Empty list when no errors were captured on this beacon."},"slowest_resource_duration":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Slowest Resource Duration"},"resource_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Resource Count"},"bfcache_hit":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Bfcache Hit"},"nav_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nav Type"},"protocol":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Protocol"},"lcp_element":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lcp Element"},"lcp_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lcp Url"},"cls_element":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cls Element"},"third_party_duration":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Third Party Duration"},"third_party_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Third Party Count"},"connection_rtt":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Connection Rtt"},"connection_downlink":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Connection Downlink"},"visibility_dirty":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Visibility Dirty"},"prerendered":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Prerendered"},"activation_delta":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Activation Delta"},"lcp_is_image":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Lcp Is Image"},"lcp_discovered_via":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lcp Discovered Via"},"dominant_third_party_category":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Dominant Third Party Category"},"loaf_count":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Loaf Count"},"loaf_total_duration":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Loaf Total Duration"},"error_origin":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Error Origin"},"cdn_cache_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cdn Cache Status"},"origin_cache_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin Cache Status"},"edge_dur":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Edge Dur"},"origin_dur":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Origin Dur"},"backend_dur":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Backend Dur"},"db_dur":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Db Dur"},"cache_dur":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cache Dur"},"external_dur":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"External Dur"},"render_dur":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Render Dur"},"page_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Page Type"},"cloud_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cloud Provider"},"bot_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bot Name"},"bot_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bot Type"},"is_cloud_provider":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Cloud Provider"},"is_bot":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Bot"},"fetch_xhr_total_calls":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Fetch Xhr Total Calls"},"fetch_xhr_total_errors":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Fetch Xhr Total Errors"},"fetch_xhr_worst_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Fetch Xhr Worst Ms"},"fetch_xhrs":{"items":{"$ref":"#/components/schemas/BeaconFetchXhr"},"type":"array","title":"Fetch Xhrs","description":"Endpoints this pageview called (fetch_xhr_endpoints)"},"fetch_xhr_outliers":{"items":{"$ref":"#/components/schemas/BeaconFetchXhrOutlier"},"type":"array","title":"Fetch Xhr Outliers","description":"Slow fetch_xhrs (>500ms) on this pageview"},"server_timing":{"items":{"$ref":"#/components/schemas/BeaconServerTiming"},"type":"array","title":"Server Timing","description":"Server-Timing custom keys (server_timing_dur map)"},"loaf":{"items":{"$ref":"#/components/schemas/BeaconLoAF"},"type":"array","title":"Loaf","description":"Long-Animation-Frame per-script attribution on this pageview (loaf Nested)"},"third_party_by_category":{"additionalProperties":{"type":"integer"},"type":"object","title":"Third Party By Category","description":"Third-party blocking time by category (category → ms)"},"third_parties":{"additionalProperties":{"type":"integer"},"type":"object","title":"Third Parties","description":"Third-party blocking time by domain (domain → ms). Empty for beacons ingested in ANONYMOUS mode (domain keys suppressed at the edge)."},"resource_counts":{"additionalProperties":{"type":"integer"},"type":"object","title":"Resource Counts","description":"Resource count by type (type → count)"},"resource_sizes":{"additionalProperties":{"type":"integer"},"type":"object","title":"Resource Sizes","description":"Resource transfer size by type (type → bytes)"},"resource_durations":{"additionalProperties":{"type":"integer"},"type":"object","title":"Resource Durations","description":"Resource duration by type (type → ms)"}},"type":"object","required":["started_at","ended_at","session_id","url"],"title":"BeaconRow","description":"One beacon (page view) row. Matches BEACON_ROW_FIELD_MAP.\n\nClosed schema: adding new columns requires updating both BEACON_ROW_FIELD_MAP\nand this model. The TS OpenAPI client is more useful with a closed shape than\na permissive `extra: allow`."},"BeaconServerTiming":{"properties":{"key":{"type":"string","title":"Key","description":"Server-Timing metric name"},"dur":{"type":"number","title":"Dur","description":"Reported duration (ms)"},"desc":{"type":"string","title":"Desc","description":"Server-Timing description (operator header text)","default":""}},"type":"object","required":["key","dur"],"title":"BeaconServerTiming","description":"One Server-Timing custom key on this pageview (from the server_timing_dur map)."},"BeaconsOrder":{"type":"string","enum":["started_at_desc","started_at_asc"],"title":"BeaconsOrder","description":"Sort direction for the /analytics/beacons endpoint."},"BeaconsRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"error_fingerprint":{"anyOf":[{"type":"string","maxLength":16},{"type":"null"}],"title":"Error Fingerprint","description":"Scope the list to pageviews carrying this error signature (`errors.fingerprint`). Handled here, NOT via the shared Filters, because it's a Nested-array column that only exists on `beacons` — putting it in Filters would break the rollup-routed aggregate endpoints. Powers the /error page's 'open in Explorer' drill-down."},"limit":{"type":"integer","maximum":1000.0,"minimum":1.0,"title":"Limit","description":"Max rows per page","default":100},"offset":{"type":"integer","minimum":0.0,"title":"Offset","description":"Pagination offset (0-based)","default":0},"order_by":{"$ref":"#/components/schemas/BeaconsOrder","description":"Sort order; default shows most recent first","default":"started_at_desc"},"fields":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Fields","description":"Optional field projection. Null/omitted returns the full whitelist. started_at, session_id, url are always included regardless."},"live":{"type":"boolean","title":"Live","description":"Live view: skip the 30s-cached total count so brand-new beacons surface immediately. `has_more` is derived by over-fetching one row; `total_matched` is returned as null (unknown). Use for an auto-refreshing 'latest requests' table; leave off for normal paginated browsing where the exact total matters.","default":false}},"additionalProperties":false,"type":"object","required":["time_range"],"title":"BeaconsRequest","description":"Row-level drill-down request: individual beacons matching filters.\n\nResponse shape is row-per-beacon (no metric aggregation). Pair with\n/analytics/query when the user needs to go from an aggregate row to the\nspecific beacons behind it."},"BeaconsResponse":{"properties":{"rows":{"items":{"$ref":"#/components/schemas/BeaconRow"},"type":"array","title":"Rows","description":"Matching beacons (up to limit)"},"total_matched":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Total Matched","description":"Total rows matching filters (ignoring limit/offset); UI uses this to decide whether pagination is worth showing. Null in `live` mode, where the cached count is skipped for freshness and only `has_more` is known."},"has_more":{"type":"boolean","title":"Has More","description":"More rows beyond this page. Normal mode: offset + len(rows) < total_matched. Live mode: derived by over-fetching one row."},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time"}},"type":"object","required":["rows","total_matched","has_more","execution_time_ms"],"title":"BeaconsResponse","description":"Response for /analytics/beacons."},"CollectorMode":{"type":"string","enum":["default","custom","relative"],"title":"CollectorMode","description":"How the served tracker bundle is told where to POST beacons.\n\nDEFAULT  → fastmon's shared collector (`settings.COLLECTOR_URL`); third-party.\nCUSTOM   → an explicit absolute `collector_endpoint` URL. Covers both a\n           first-party setup on the customer's own domain AND a third-party\n           custom collector host — the browser decides 1P/3P at runtime by\n           comparing that host to the page origin; we don't store which.\nRELATIVE → a host-less relative `/c/<hash>`, resolved same-origin against\n           whatever domain the page runs on. First-party without pinning a\n           host — the natural fit for an org tracker embedded across N\n           domains. `collector_endpoint` is unused (must be empty)."},"CompareMode":{"type":"string","enum":["previous_period","previous_week","previous_month"],"title":"CompareMode","description":"Comparison time range modes."},"ComparisonData":{"properties":{"metrics":{"items":{"$ref":"#/components/schemas/MetricValue"},"type":"array","title":"Metrics","description":"Comparison metric values"},"beacons":{"type":"integer","title":"Beacons","description":"Number of samples in comparison period"},"change_percent":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Change Percent","description":"Percent change from comparison (negative = improvement for timing)"}},"type":"object","required":["metrics","beacons"],"title":"ComparisonData","description":"Comparison data for a data point."},"ConditionType":{"type":"string","enum":["absolute","relative_change"],"title":"ConditionType"},"CursorPaginatedResponse_VisitorSummaryItem_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/VisitorSummaryItem"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/CursorPaginationMeta"}},"type":"object","required":["data","meta"],"title":"CursorPaginatedResponse[VisitorSummaryItem]"},"CursorPaginationMeta":{"properties":{"limit":{"type":"integer","title":"Limit"},"has_more":{"type":"boolean","title":"Has More"},"next_cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Next Cursor"}},"type":"object","required":["limit","has_more"],"title":"CursorPaginationMeta","description":"Meta for ClickHouse-backed cursor-paginated lists.\n\n`total` is intentionally absent: COUNT(*) over beacon tables is too\nexpensive. Clients rely on `has_more` + `next_cursor` instead."},"DeviceComparison":{"properties":{"device":{"type":"string","title":"Device"},"lab_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lab Score"},"experience_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Experience Score"},"experience_grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Experience Grade"},"field_samples":{"type":"integer","title":"Field Samples"},"field_sufficient":{"type":"boolean","title":"Field Sufficient"},"metrics":{"items":{"$ref":"#/components/schemas/MetricComparison"},"type":"array","title":"Metrics"},"field_inp_p75":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Field Inp P75"},"lab_tbt":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lab Tbt"}},"type":"object","required":["device","lab_score","experience_score","experience_grade","field_samples","field_sufficient","metrics","field_inp_p75","lab_tbt"],"title":"DeviceComparison"},"ElementTargetItem":{"properties":{"target":{"type":"string","title":"Target","description":"Bounded CSS selector path (e.g. '#hero>img.banner')"},"count":{"type":"integer","title":"Count","description":"Pageviews attributing this target (exact)"},"share_pct":{"type":"number","title":"Share Pct","description":"Share of the group's attributed pageviews (0-100)"},"avg_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Value","description":"Average metric value on those pageviews (ms for lcp/inp, score for cls)"}},"type":"object","required":["target","count","share_pct"],"title":"ElementTargetItem","description":"One ranked element target within a group."},"ElementTargetsGroup":{"properties":{"key":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Key","description":"Group key (URL), null for group_by=none"},"pageviews_with_target":{"type":"integer","title":"Pageviews With Target","description":"Pageviews in this group carrying a non-empty target"},"targets":{"items":{"$ref":"#/components/schemas/ElementTargetItem"},"type":"array","title":"Targets","description":"Ranked targets, most frequent first"}},"type":"object","required":["pageviews_with_target","targets"],"title":"ElementTargetsGroup","description":"Ranked targets for one group (one URL, or the whole scope)."},"ElementTargetsRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query (required)"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"metric":{"type":"string","enum":["lcp","cls","inp"],"title":"Metric","description":"Which vital's element attribution to rank"},"by":{"type":"string","enum":["element","resource_url"],"title":"By","description":"'element' ranks the CSS selector path; 'resource_url' ranks the LCP resource URL (only valid for metric='lcp')","default":"element"},"group_by":{"type":"string","enum":["none","url"],"title":"Group By","description":"'url' ranks targets per page; 'none' site-wide","default":"none"},"limit":{"type":"integer","maximum":25.0,"minimum":1.0,"title":"Limit","description":"Top-N targets per group","default":10},"groups_limit":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Groups Limit","description":"Top-N groups by attributed pageviews (group_by=url)","default":20}},"additionalProperties":false,"type":"object","required":["time_range","metric"],"title":"ElementTargetsRequest","description":"Request for the element-targets breakdown (migration-053 selector paths).\n\nGeneric over the three attributed vitals: which ELEMENT is the LCP /\nthe largest layout shift / the reported INP interaction target. The\nselector columns are deliberately not query-builder dimensions\n(high-cardinality GROUP BY hazard); this endpoint ranks them via a\nbounded-state topK instead."},"ElementTargetsResponse":{"properties":{"metric":{"type":"string","title":"Metric","description":"The requested vital (lcp/cls/inp)"},"groups":{"items":{"$ref":"#/components/schemas/ElementTargetsGroup"},"type":"array","title":"Groups","description":"group_by=none → exactly one group; group_by=url → top groups"},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time"}},"type":"object","required":["metric","groups","execution_time_ms"],"title":"ElementTargetsResponse","description":"Response for the element-targets breakdown."},"Environment":{"type":"string","enum":["prod","dev"],"title":"Environment","description":"Deployment environment of an application. Billing-relevant: PROD apps are\nbilled, DEV apps are not (see the billing module). Defaults to PROD — the\nrevenue-safe fallback, so a forgotten value is never silently unbilled."},"ErrorBody":{"properties":{"code":{"type":"string","title":"Code"},"message":{"type":"string","title":"Message"},"request_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Request Id"},"doc_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Doc Url"},"details":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Details"}},"type":"object","required":["code","message"],"title":"ErrorBody"},"ErrorBreakdown":{"properties":{"top":{"items":{"$ref":"#/components/schemas/ErrorBreakdownEntry"},"type":"array","title":"Top","description":"Top-N entries, desc by count"},"distinct_total":{"type":"integer","title":"Distinct Total","description":"Total distinct values across the dimension"}},"type":"object","required":["top","distinct_total"],"title":"ErrorBreakdown","description":"Top-N plus totals for one breakdown dimension."},"ErrorBreakdownDim":{"type":"string","enum":["url","browser","device","os","country"],"title":"ErrorBreakdownDim","description":"Dimensions available for error detail breakdowns."},"ErrorBreakdownEntry":{"properties":{"key":{"type":"string","title":"Key","description":"Dimension value (e.g. a URL, browser name)"},"count":{"type":"integer","title":"Count","description":"Error occurrences for this value"},"visitors":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Visitors","description":"Distinct affected visitors for this value, counted over the response's resolved `identity` (stitch or session). Null if the site collects no visitor identifier."}},"type":"object","required":["key","count"],"title":"ErrorBreakdownEntry","description":"One row in a breakdown histogram."},"ErrorDetailRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"identity":{"anyOf":[{"type":"string","enum":["stitch","session"]},{"type":"null"}],"title":"Identity","description":"Identity backing `visitors_affected` / breakdown `visitors`: 'stitch' or 'session'. Null resolves to the per-site default."},"fingerprint":{"type":"string","maxLength":16,"minLength":1,"title":"Fingerprint"},"breakdowns":{"items":{"$ref":"#/components/schemas/ErrorBreakdownDim"},"type":"array","title":"Breakdowns","description":"Dimensions to return as top-N breakdowns"},"limit":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Limit","description":"Max entries per breakdown dimension","default":10},"sample_size":{"type":"integer","maximum":100.0,"minimum":0.0,"title":"Sample Size","default":20},"granularity":{"anyOf":[{"type":"string","enum":["hour","day"]},{"type":"string","const":"auto"}],"title":"Granularity","description":"Time-series bucket: 'hour'/'day', or 'auto' (derived from the time range)","default":"auto"}},"additionalProperties":false,"type":"object","required":["time_range","fingerprint"],"title":"ErrorDetailRequest","description":"Request for drill-down on a single error signature.\n\nIdentified by `fingerprint` (server-computed canonical key), not the\nlegacy 4-tuple. Backfillable: if the fingerprint rule changes, an\nUPDATE rewrites every row deterministically; old request URLs become\ninvalid by design rather than silently matching the wrong bucket."},"ErrorDetailResponse":{"properties":{"summary":{"$ref":"#/components/schemas/ErrorDetailSummary"},"identity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Identity","description":"Resolved identity backing the affected-visitor counts (stitch|session); null = site collects neither identifier."},"timeseries":{"items":{"$ref":"#/components/schemas/ErrorTimeseriesPoint"},"type":"array","title":"Timeseries"},"breakdowns":{"additionalProperties":{"$ref":"#/components/schemas/ErrorBreakdown"},"type":"object","title":"Breakdowns"},"samples":{"items":{"$ref":"#/components/schemas/ErrorSample"},"type":"array","title":"Samples"},"execution_time_ms":{"type":"number","title":"Execution Time Ms"}},"type":"object","required":["summary","timeseries","breakdowns","samples","execution_time_ms"],"title":"ErrorDetailResponse","description":"Response for `/analytics/error-types/detail`."},"ErrorDetailSummary":{"properties":{"count":{"type":"integer","title":"Count"},"visitors_affected":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Visitors Affected","description":"Distinct affected visitors, counted over the response's resolved `identity` (stitch or session). Null if the site collects no visitor identifier."},"first_seen":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"First Seen"},"last_seen":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Seen"},"percentage_of_total":{"type":"number","title":"Percentage Of Total"}},"type":"object","required":["count","percentage_of_total"],"title":"ErrorDetailSummary","description":"Aggregate summary for the selected error."},"ErrorFrameInfo":{"properties":{"host":{"type":"string","title":"Host","description":"Source-script hostname (no port/query)."},"path":{"type":"string","title":"Path","description":"Sanitized script path; '' on host-only frames.","default":""},"line":{"type":"integer","title":"Line","description":"Line number in the bundled file."},"column":{"type":"integer","title":"Column","description":"Column number in the bundled file."}},"type":"object","required":["host","line","column"],"title":"ErrorFrameInfo","description":"One stack frame surfaced to the dashboard.\n\nThe fields mirror the storage shape (`errors.frame_hosts/paths/lines/\ncols` per error): hostname + sanitized script path — never a query\nstring or token. `path` is \"\" wherever the wire carried a host-only\nframe: on the without-consent wire everything except first-party\nEXTERNAL script frames (docs/data_collection.md §3.9), plus rows\npredating migration 033. line/col are the raw positions; resolving\nthem to source-mapped locations is a future server-side concern, not\npart of this schema."},"ErrorResponse":{"properties":{"error":{"$ref":"#/components/schemas/ErrorBody"}},"type":"object","required":["error"],"title":"ErrorResponse"},"ErrorSample":{"properties":{"started_at":{"type":"string","format":"date-time","title":"Started At","description":"Pageview start where the error occurred"},"url":{"type":"string","title":"Url"},"session_id":{"type":"string","title":"Session Id"},"browser":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Browser"},"device":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Device"},"os":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Os"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country"}},"type":"object","required":["started_at","url","session_id"],"title":"ErrorSample","description":"Recent beacon exhibiting this error."},"ErrorTimeseriesPoint":{"properties":{"t":{"type":"string","format":"date-time","title":"T"},"count":{"type":"integer","title":"Count"}},"type":"object","required":["t","count"],"title":"ErrorTimeseriesPoint","description":"One point in the error time series."},"ErrorTypeItem":{"properties":{"fingerprint":{"type":"string","title":"Fingerprint","description":"Stable group-by key for this error signature."},"error_type":{"type":"string","title":"Error Type","description":"Error type name (e.g., 'TypeError')"},"count":{"type":"integer","title":"Count","description":"Number of occurrences"},"percentage":{"type":"number","title":"Percentage","description":"Percentage of total errors"},"sample_message":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Sample Message","description":"One example error message captured for this signature, PII-stripped and capped at 80 chars. Sourced from `errors.sample_message`."},"is_first_party":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is First Party","description":"True if any captured frame's host equals the page host (server-derived). `None` if mixed across the aggregated group."},"frames":{"items":{"$ref":"#/components/schemas/ErrorFrameInfo"},"type":"array","title":"Frames","description":"Captured stack frames (max 5). frames[0] is the innermost throw site; frames[1+] expose the caller chain past framework/wrapper frames."}},"type":"object","required":["fingerprint","error_type","count","percentage"],"title":"ErrorTypeItem","description":"One error signature, keyed by `fingerprint`.\n\n`fingerprint` is the canonical group-by handle (server-computed djb2\nhash over type + frames + sample_message). All other fields are\ndisplay projections of one row in that group."},"ErrorTypesRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"error_type":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Error Type","description":"Restrict to specific error types (e.g. ['ResourceLoadError'])."},"exclude_error_type":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Exclude Error Type","description":"Drop these error types from the breakdown (e.g. ['ResourceLoadError'] to stop third-party resource-load noise from counting). Negative of error_type."},"exclude_hosts":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Exclude Hosts","description":"Exclude error signatures whose stack frames touch any of these hosts (e.g. ['bat.bing.com'] to drop a noisy 3rd-party)."},"first_party":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"First Party","description":"Restrict to first-party (True) or third-party (False) error signatures. Matches per-signature `errors.is_first_party` (filter-then-rank: the Top-N reflects the chosen group). None = both. Note: signature-accurate, unlike the page-level `filters.error_origin` (which is the dominant error's origin per beacon)."},"limit":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Limit","description":"Max error types to return","default":10}},"additionalProperties":false,"type":"object","required":["time_range"],"title":"ErrorTypesRequest","description":"Request for error types breakdown."},"ErrorTypesResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/ErrorTypeItem"},"type":"array","title":"Data","description":"Error types with counts"},"total_errors":{"type":"integer","title":"Total Errors","description":"Total error count (excludes ad-blocked trackers)"},"blocked_count":{"type":"integer","title":"Blocked Count","description":"Ad-blocked tracker errors (errors.class='blocked') excluded from total_errors in the same filter scope — surface as 'N excluded as ad-blocked', not as a failure.","default":0},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time"}},"type":"object","required":["data","total_errors","execution_time_ms"],"title":"ErrorTypesResponse","description":"Response for error types breakdown."},"EvaluateResponse":{"properties":{"rule_id":{"type":"string","format":"uuid","title":"Rule Id"},"evaluated_at":{"type":"string","format":"date-time","title":"Evaluated At"},"results":{"items":{"$ref":"#/components/schemas/EvaluateSiteResult"},"type":"array","title":"Results"}},"type":"object","required":["rule_id","evaluated_at","results"],"title":"EvaluateResponse"},"EvaluateSiteResult":{"properties":{"site_id":{"type":"string","format":"uuid","title":"Site Id"},"domain":{"type":"string","title":"Domain"},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value"},"is_condition_met":{"type":"boolean","title":"Is Condition Met"},"reason":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Reason"}},"type":"object","required":["site_id","domain","value","is_condition_met"],"title":"EvaluateSiteResult"},"ExcludeColumn":{"type":"string","enum":["browser","device_type","os","country","connection_type","nav_type","protocol","viewport_class","dominant_third_party_category","error_origin","cdn_cache_status","origin_cache_status","page_type","tracker_version","cloud_provider","bot_name","bot_type"],"title":"ExcludeColumn","description":"Columns allowed as Filters.exclude keys (NOT IN)."},"ExperienceScoreMetric":{"properties":{"metric":{"type":"string","title":"Metric","description":"Metric name (e.g., lcp, inp)"},"value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Value","description":"Raw metric value (p75)"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score","description":"Metric score 0.0–10.0"}},"type":"object","required":["metric"],"title":"ExperienceScoreMetric","description":"Score for a single metric within a segment."},"ExperienceScoreRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query (required)"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"}},"additionalProperties":false,"type":"object","required":["time_range"],"title":"ExperienceScoreRequest","description":"Request schema for experience score query."},"ExperienceScoreResponse":{"properties":{"segments":{"items":{"$ref":"#/components/schemas/ExperienceScoreSegment"},"type":"array","title":"Segments","description":"Scores per visitor segment"},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time"}},"type":"object","required":["segments","execution_time_ms"],"title":"ExperienceScoreResponse","description":"Response for experience score query."},"ExperienceScoreSegment":{"properties":{"segment":{"type":"string","title":"Segment","description":"Segment key (all, desktop, mobile, slow)"},"label":{"type":"string","title":"Label","description":"Human-readable segment name"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score","description":"Overall score 0.0–10.0"},"grade":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Grade","description":"Letter grade (A+, A, B, C, D, F)"},"beacon_count":{"type":"integer","title":"Beacon Count","description":"Number of beacons in segment"},"metrics":{"items":{"$ref":"#/components/schemas/ExperienceScoreMetric"},"type":"array","title":"Metrics","description":"Per-metric breakdown"}},"type":"object","required":["segment","label","beacon_count","metrics"],"title":"ExperienceScoreSegment","description":"Experience score for one visitor segment."},"FetchXhrDetailRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"host":{"type":"string","title":"Host","description":"Target host ('' = same-origin) — the drill-down key"},"method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method","description":"Optional HTTP-method refinement"},"path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path","description":"Optional path refinement (one endpoint)"},"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","description":"Max rows per block (pages/endpoints/outliers)","default":20},"order_by":{"type":"string","enum":["impact","errors","error_rate","calls"],"title":"Order By","description":"Sort key for the `pages` block","default":"impact"},"outliers":{"type":"string","enum":["slowest","failed"],"title":"Outliers","description":"Trace sample: 'slowest' (default) or 'failed' (only status >= 400)","default":"slowest"}},"additionalProperties":false,"type":"object","required":["time_range","host"],"title":"FetchXhrDetailRequest","description":"Drill-down keyed by `host` (the fetch_xhr analogue of the error-fingerprint\ndetail). `method`/`path` are optional refinements: omit them for a HOST-level\nview (all endpoints of that host), give `path` to scope to one endpoint.\nAnswers \"where do this host's calls run, and which fail (status + page)?\"."},"FetchXhrDetailResponse":{"properties":{"host":{"type":"string","title":"Host","description":"Echoed host"},"method":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Method","description":"Echoed method refinement (None = all)"},"path":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Path","description":"Echoed path refinement (None = all)"},"calls":{"type":"integer","title":"Calls","description":"Total calls in scope"},"errors":{"type":"integer","title":"Errors","description":"Total errored calls in scope"},"error_rate":{"type":"number","title":"Error Rate","description":"errors / calls"},"avg_ms":{"type":"number","title":"Avg Ms","description":"sum_ms / calls"},"max_ms":{"type":"integer","title":"Max Ms","description":"Slowest single call in scope"},"impact_ms":{"type":"integer","title":"Impact Ms","description":"sum_ms — total wall time in scope"},"endpoints":{"items":{"$ref":"#/components/schemas/FetchXhrEndpointItem"},"type":"array","title":"Endpoints","description":"Per (method, path) within the host, by impact"},"pages":{"items":{"$ref":"#/components/schemas/FetchXhrPageItem"},"type":"array","title":"Pages","description":"Per page (url) in scope, by impact"},"outliers":{"items":{"$ref":"#/components/schemas/FetchXhrOutlierItem"},"type":"array","title":"Outliers","description":"Individual trace calls (slow/failed) in scope — status + page"},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time"}},"type":"object","required":["host","calls","errors","error_rate","avg_ms","max_ms","impact_ms","endpoints","pages","outliers","execution_time_ms"],"title":"FetchXhrDetailResponse","description":"Host (or endpoint) drill-down: overall stats + per-endpoint, per-page and\nthe individual trace calls (slow/failed, with status + page)."},"FetchXhrEndpointItem":{"properties":{"method":{"type":"string","title":"Method","description":"HTTP method (GET/POST/... or 'other')"},"host":{"type":"string","title":"Host","description":"Target host ('' = same-origin as the page)"},"path":{"type":"string","title":"Path","description":"Templated path (/api/users/:id)"},"calls":{"type":"integer","title":"Calls","description":"Calls to this endpoint"},"avg_ms":{"type":"number","title":"Avg Ms","description":"sum_ms / calls"},"max_ms":{"type":"integer","title":"Max Ms","description":"Slowest single call to this endpoint"},"errors":{"type":"integer","title":"Errors","description":"Errored calls"},"error_rate":{"type":"number","title":"Error Rate","description":"errors / calls"},"impact_ms":{"type":"integer","title":"Impact Ms","description":"Σ per-call duration (sum_ms) — frequency × latency, the impact sort key. NOT wall-clock: fetch/XHR run concurrently, so this overcounts vs elapsed time."},"status_errors":{"additionalProperties":{"type":"integer"},"type":"object","title":"Status Errors","description":"Error-status distribution over ALL calls: HTTP code → count (0 = network failure). Complete, unlike the outlier trace sample."},"p75_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"P75 Ms","description":"Approx p75 latency from the histogram"},"p95_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"P95 Ms","description":"Approx p95 latency from the histogram"},"avg_offset_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Avg Offset Ms","description":"Ø Start-Offset ab Pageview-Start (sum_offset_ms/calls) — die Balken-Position im Aggregat-Waterfall; null wenn nicht erfasst."},"sync_calls":{"type":"integer","title":"Sync Calls","description":"Synchronous XHR (main-thread-blocking) calls","default":0},"aborts":{"type":"integer","title":"Aborts","description":"Aborted calls (user/navigation cancellation)","default":0},"blocked":{"type":"integer","title":"Blocked","description":"Status-0 calls to known ad/analytics/tracker hosts, classified server-side as ad-blocked (not real failures) and excluded from `errors`.","default":0},"avg_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Avg Bytes","description":"sum_bytes / calls, averaged over ALL calls (cache hits and cross-origin-masked calls count as 0 bytes, so this under-reports for cache-heavy endpoints); null only when every call reported 0 bytes."},"max_bytes":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Max Bytes","description":"Largest single response (bytes); null when masked"}},"type":"object","required":["method","host","path","calls","avg_ms","max_ms","errors","error_rate","impact_ms"],"title":"FetchXhrEndpointItem","description":"One endpoint template, aggregated over all pageviews (the `other` rollup\nbucket is excluded — it's only reflected in totals)."},"FetchXhrOutlierItem":{"properties":{"method":{"type":"string","title":"Method","description":"HTTP method"},"host":{"type":"string","title":"Host","description":"Target host ('' = same-origin)"},"path":{"type":"string","title":"Path","description":"Templated path"},"duration_ms":{"type":"integer","title":"Duration Ms","description":"Call duration (ms)"},"status":{"type":"integer","title":"Status","description":"HTTP status (0 = network error / unknown)"},"ttfb_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Ttfb Ms","description":"TTFB (ms); null = cross-origin masked"},"page":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Page","description":"Page URL the call ran on (the beacon's `url`)"},"server_timing":{"additionalProperties":{"type":"number"},"type":"object","title":"Server Timing","description":"The call's own backend phases (name → ms) from Server-Timing — the mini-waterfall; same-origin/TAO only (empty cross-origin)."}},"type":"object","required":["method","host","path","duration_ms","status"],"title":"FetchXhrOutlierItem","description":"One slow individual call (>500 ms) for debug context."},"FetchXhrPageItem":{"properties":{"url":{"type":"string","title":"Url","description":"Page URL"},"calls":{"type":"integer","title":"Calls","description":"Calls to the endpoint from this page"},"avg_ms":{"type":"number","title":"Avg Ms","description":"sum_ms / calls"},"max_ms":{"type":"integer","title":"Max Ms","description":"Slowest single call from this page"},"errors":{"type":"integer","title":"Errors","description":"Errored calls"},"error_rate":{"type":"number","title":"Error Rate","description":"errors / calls"},"impact_ms":{"type":"integer","title":"Impact Ms","description":"sum_ms — total wall time, the impact sort key"},"status_errors":{"additionalProperties":{"type":"integer"},"type":"object","title":"Status Errors","description":"Error-status distribution on this page: HTTP code → count (0 = network)."}},"type":"object","required":["url","calls","avg_ms","max_ms","errors","error_rate","impact_ms"],"title":"FetchXhrPageItem","description":"One page an endpoint runs on, aggregated over all pageviews of that page."},"FetchXhrRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","description":"Max endpoints (endpoints block)","default":20},"outlier_limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Outlier Limit","description":"Max outliers","default":20}},"additionalProperties":false,"type":"object","required":["time_range"],"title":"FetchXhrRequest","description":"Request for the fetch_xhr (fetch/XHR) dashboard panel."},"FetchXhrResponse":{"properties":{"totals":{"$ref":"#/components/schemas/FetchXhrTotals","description":"Aggregate counters"},"endpoints":{"items":{"$ref":"#/components/schemas/FetchXhrEndpointItem"},"type":"array","title":"Endpoints","description":"Per-endpoint aggregates"},"outliers":{"items":{"$ref":"#/components/schemas/FetchXhrOutlierItem"},"type":"array","title":"Outliers","description":"Slowest individual calls"},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time"}},"type":"object","required":["totals","endpoints","outliers","execution_time_ms"],"title":"FetchXhrResponse","description":"Response for the fetch_xhr dashboard panel: three blocks."},"FetchXhrTotals":{"properties":{"calls":{"type":"integer","title":"Calls","description":"Total fetch_xhr calls"},"errors":{"type":"integer","title":"Errors","description":"Total fetch_xhr errors (status >= 400 or 0)"},"error_rate":{"type":"number","title":"Error Rate","description":"errors / calls (0 when no calls)"},"worst_ms":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Worst Ms","description":"Slowest single observed call (ms)"}},"type":"object","required":["calls","errors","error_rate"],"title":"FetchXhrTotals","description":"Aggregate fetch_xhr counters across the queried scope."},"FieldPoint":{"properties":{"ts":{"type":"string","title":"Ts"},"samples":{"type":"integer","title":"Samples"},"lcp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lcp"},"fcp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fcp"},"cls":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cls"},"inp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inp"},"ttfb":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ttfb"}},"type":"object","required":["ts","samples","lcp","fcp","cls","inp","ttfb"],"title":"FieldPoint","description":"One RUM bucket (regular). p75 per metric (ms; cls unitless)."},"Filters":{"properties":{"site_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Site Id","description":"Filter by specific site"},"site_ids":{"anyOf":[{"items":{"type":"string","format":"uuid"},"type":"array","minItems":1},{"type":"null"}],"title":"Site Ids","description":"Filter by multiple sites (OR). Must be non-empty when present — an empty list is rejected with 422. Ignored when `site_id` is also set (precedence: site_id > site_ids > application_id > tags)."},"application_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Application Id","description":"Filter to every domain (site) of one application — the aggregated per-application scope. Resolved to the app's site_ids. Ignored when a higher-precedence site filter is set (precedence: site_id > site_ids > application_id > tags)."},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tags","description":"Filter by site tags (AND semantics)"},"browser":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Browser","description":"Filter by browsers"},"device_type":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Device Type","description":"Filter by device types"},"os":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Os","description":"Filter by OS"},"country":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Country","description":"Filter by countries (ISO codes)"},"connection_type":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Connection Type","description":"Filter by connection types"},"url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Url","description":"Filter by URL (supports * wildcards)"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain","description":"Filter by domain"},"referrer_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Source","description":"Filter by referrer source bucket (e.g. Google, Direct)"},"referrer_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Referrer Medium","description":"Filter by Snowplow referer-parser medium (search/social/email/paid/internal/unknown)"},"utm_source":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Source","description":"Filter by UTM source bucket (marketer-set, e.g. google, newsletter)"},"utm_medium":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Medium","description":"Filter by UTM medium (marketer-set, e.g. cpc, email, social)"},"utm_campaign":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Campaign","description":"Filter by UTM campaign identifier"},"utm_term":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Term","description":"Filter by UTM term (PPC keyword). High cardinality: useful for scoping a query, less so as a group-by dimension."},"utm_content":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Utm Content","description":"Filter by UTM content (A/B variant / ad creative ID). High cardinality: useful for A/B comparisons, less so as a group-by dimension."},"click_id_param":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Click Id Param","description":"Filter by ad-platform click-ID label (gclid/fbclid/msclkid/...)"},"nav_type":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Nav Type","description":"Filter by navigation type (navigate/reload/back_forward/prerender/softnav)"},"protocol":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Protocol","description":"Filter by protocol (h2/h3/http1.1)"},"viewport_class":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Viewport Class","description":"Filter by viewport class (mobile/tablet/desktop/large)"},"dominant_third_party_category":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Dominant Third Party Category","description":"Filter by dominant third-party category (analytics/ads/tag-manager/...)"},"error_origin":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Error Origin","description":"Filter by error origin (first_party/third_party/none)"},"cdn_cache_status":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Cdn Cache Status","description":"Filter by CDN cache status (HIT/MISS/EXPIRED/...). The empty string '' is a valid value and matches pageviews that reported no CDN cache status at all."},"origin_cache_status":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Origin Cache Status","description":"Filter by origin/FPC cache status (HIT/MISS/...). The empty string '' is a valid value and matches pageviews that reported no origin cache status at all."},"page_type":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Page Type","description":"Filter by page type (product/category/cart/...)"},"cloud_provider":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Cloud Provider","description":"Filter by cloud/crawler network label (aws/hetzner/googlebot/...). The empty string '' is a valid value and matches normal (non-datacenter) traffic - e.g. exclude={'cloud_provider': ['']} keeps ONLY datacenter traffic, while cloud_provider=[''] keeps only residential traffic."},"bot_name":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Bot Name","description":"Filter by detected bot slug (googlebot/gptbot/...; the reserved 'unknown' = generic bot heuristics matched without a named entry). The empty string '' matches traffic with no bot signal - bot_name=[''] is the 'humans only' filter."},"bot_type":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Bot Type","description":"Filter by bot category tag (ai-crawler/search-engine/seo/monitoring/...). '' matches traffic with no bot signal."},"is_bot":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Bot","description":"Derived boolean filter: true = only detected bots (any bot_name incl. 'unknown'), false = humans only (no bot signal). Shorthand for bot_name != '' / = ''."},"is_cloud_provider":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Cloud Provider","description":"Derived boolean filter: true = only traffic from known hosting/crawler networks, false = residential networks only. Shorthand for cloud_provider != '' / = ''."},"pvid":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Pvid","description":"Filter by pageview ID(s) — e.g. to share / deep-link a specific beacon (all beacons of that pageview). Exact match (IN)."},"stitch":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Stitch","description":"Filter by stitch visitor ID(s) — the 32-hex edge-computed identity (`lower(hex(stitch))` as surfaced by /analytics/beacons). Exact match (IN). Values that aren't 32 lowercase-hex chars are dropped; an all-invalid filter matches nothing."},"tracker_version":{"anyOf":[{"items":{"type":"string"},"type":"array"},{"type":"null"}],"title":"Tracker Version","description":"Filter by tracker bundle version (e.g. rollout debugging)"},"metric_ranges":{"anyOf":[{"items":{"$ref":"#/components/schemas/MetricRange"},"type":"array"},{"type":"null"}],"title":"Metric Ranges","description":"Numeric threshold filters (gte/lte) on beacon metrics — e.g. {metric:'lcp', gte:2500} for slow-LCP pageviews, or {metric:'error_count', gte:1} for pageviews with errors. Also carries the browser MAJOR version: {metric:'browser_version', gte:150} = 'browser >= 150' (pair with a `browser` family filter for 'Chrome >= 150'). Multiple are ANDed."},"exclude":{"anyOf":[{"additionalProperties":{"items":{"type":"string"},"type":"array"},"propertyNames":{"$ref":"#/components/schemas/ExcludeColumn"},"type":"object"},{"type":"null"}],"title":"Exclude","description":"Negative filters: column → values to EXCLUDE (NOT IN). Keys are the allowlisted categorical columns (see the ExcludeColumn enum in the schema). e.g. {'country': ['DE','NL']} drops DE+NL; multiple columns are ANDed. Complements the positive (IN) filters above.","examples":[{"country":["DE","NL"]}]}},"additionalProperties":false,"type":"object","title":"Filters","description":"Query filters for narrowing down results."},"Granularity":{"type":"string","enum":["none","minute","hour","day","week","month"],"title":"Granularity","description":"Time bucketing granularity for GROUP BY."},"GroupBy":{"properties":{"granularity":{"$ref":"#/components/schemas/Granularity","description":"Time bucket granularity for grouping","default":"none"},"dimensions":{"items":{"anyOf":[{"type":"string"},{"$ref":"#/components/schemas/MapDimension"}]},"type":"array","maxItems":2,"title":"Dimensions","description":"Dimensions to group by (max 2). Strings for flat or Nested (errors.*) columns; objects for Map columns."}},"type":"object","title":"GroupBy","description":"Grouping configuration for queries."},"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"HistogramBucket":{"properties":{"bucket":{"type":"string","title":"Bucket","description":"Bucket label (e.g., '0-500ms')"},"min_value":{"type":"number","title":"Min Value","description":"Minimum value for this bucket (inclusive)"},"max_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Max Value","description":"Maximum value for this bucket (exclusive, None for last bucket)"},"count":{"type":"integer","title":"Count","description":"Number of samples in this bucket"},"percentage":{"type":"number","title":"Percentage","description":"Percentage of total samples"}},"type":"object","required":["bucket","min_value","max_value","count","percentage"],"title":"HistogramBucket","description":"Single bucket in a histogram."},"HistogramMeta":{"properties":{"total_samples":{"type":"integer","title":"Total Samples","description":"Total samples in histogram"},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time in milliseconds"},"metric":{"type":"string","title":"Metric","description":"Metric used for histogram"},"time_range":{"additionalProperties":true,"type":"object","title":"Time Range","description":"Applied time range"},"applied_filters":{"additionalProperties":true,"type":"object","title":"Applied Filters","description":"Applied filter values"}},"type":"object","required":["total_samples","execution_time_ms","metric","time_range","applied_filters"],"title":"HistogramMeta","description":"Metadata about histogram query execution."},"HistogramRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query (required)"},"metric":{"type":"string","title":"Metric","description":"Metric to create histogram for (e.g., lcp, ttfb)"},"buckets":{"items":{"type":"number"},"type":"array","maxItems":20,"minItems":2,"title":"Buckets","description":"Bucket boundaries (e.g., [0, 500, 1000, 2500, 4000] creates 5 buckets)"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"}},"additionalProperties":false,"type":"object","required":["time_range","metric","buckets"],"title":"HistogramRequest","description":"Request schema for histogram queries."},"HistogramResponse":{"properties":{"buckets":{"items":{"$ref":"#/components/schemas/HistogramBucket"},"type":"array","title":"Buckets","description":"Histogram buckets with counts"},"meta":{"$ref":"#/components/schemas/HistogramMeta","description":"Query metadata"}},"type":"object","required":["buckets","meta"],"title":"HistogramResponse","description":"Response for histogram queries."},"InviteCreate":{"properties":{"email":{"type":"string","format":"email","title":"Email"},"role":{"$ref":"#/components/schemas/Role","default":"member"}},"type":"object","required":["email"],"title":"InviteCreate"},"InviteResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"email":{"type":"string","title":"Email"},"role":{"$ref":"#/components/schemas/Role"},"invited_by_id":{"type":"string","format":"uuid","title":"Invited By Id"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"expires_at":{"type":"string","format":"date-time","title":"Expires At"}},"type":"object","required":["id","email","role","invited_by_id","created_at","expires_at"],"title":"InviteResponse"},"IssueActor":{"type":"string","enum":["system","user","ai"],"title":"IssueActor"},"IssueCategory":{"type":"string","enum":["web_vitals","errors","traffic","fetch"],"title":"IssueCategory"},"IssueComment":{"properties":{"comment":{"type":"string","maxLength":2000,"minLength":1,"title":"Comment"}},"type":"object","required":["comment"],"title":"IssueComment"},"IssueDetailResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"organization_id":{"type":"string","format":"uuid","title":"Organization Id"},"application_id":{"type":"string","format":"uuid","title":"Application Id"},"site_id":{"type":"string","format":"uuid","title":"Site Id"},"detector_key":{"type":"string","title":"Detector Key"},"fingerprint":{"type":"string","title":"Fingerprint"},"category":{"$ref":"#/components/schemas/IssueCategory"},"severity":{"$ref":"#/components/schemas/IssueSeverity"},"status":{"$ref":"#/components/schemas/IssueStatus"},"is_shadow":{"type":"boolean","title":"Is Shadow"},"title":{"type":"string","title":"Title"},"summary":{"type":"string","title":"Summary"},"evidence":{"additionalProperties":true,"type":"object","title":"Evidence"},"first_seen_at":{"type":"string","format":"date-time","title":"First Seen At"},"last_seen_at":{"type":"string","format":"date-time","title":"Last Seen At"},"opened_at":{"type":"string","format":"date-time","title":"Opened At"},"resolved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Resolved At"},"muted_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Muted Until"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"events":{"items":{"$ref":"#/components/schemas/IssueEventResponse"},"type":"array","title":"Events"}},"type":"object","required":["id","organization_id","application_id","site_id","detector_key","fingerprint","category","severity","status","is_shadow","title","summary","evidence","first_seen_at","last_seen_at","opened_at","created_at","updated_at"],"title":"IssueDetailResponse"},"IssueEventResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"type":{"$ref":"#/components/schemas/IssueEventType"},"actor":{"$ref":"#/components/schemas/IssueActor"},"actor_user_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Actor User Id"},"value_snapshot":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Value Snapshot"},"comment":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Comment"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","type","actor","created_at"],"title":"IssueEventResponse"},"IssueEventType":{"type":"string","enum":["opened","updated","escalated","resolved","regressed","muted","unmuted","comment"],"title":"IssueEventType"},"IssueResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"organization_id":{"type":"string","format":"uuid","title":"Organization Id"},"application_id":{"type":"string","format":"uuid","title":"Application Id"},"site_id":{"type":"string","format":"uuid","title":"Site Id"},"detector_key":{"type":"string","title":"Detector Key"},"fingerprint":{"type":"string","title":"Fingerprint"},"category":{"$ref":"#/components/schemas/IssueCategory"},"severity":{"$ref":"#/components/schemas/IssueSeverity"},"status":{"$ref":"#/components/schemas/IssueStatus"},"is_shadow":{"type":"boolean","title":"Is Shadow"},"title":{"type":"string","title":"Title"},"summary":{"type":"string","title":"Summary"},"evidence":{"additionalProperties":true,"type":"object","title":"Evidence"},"first_seen_at":{"type":"string","format":"date-time","title":"First Seen At"},"last_seen_at":{"type":"string","format":"date-time","title":"Last Seen At"},"opened_at":{"type":"string","format":"date-time","title":"Opened At"},"resolved_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Resolved At"},"muted_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Muted Until"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"}},"type":"object","required":["id","organization_id","application_id","site_id","detector_key","fingerprint","category","severity","status","is_shadow","title","summary","evidence","first_seen_at","last_seen_at","opened_at","created_at","updated_at"],"title":"IssueResponse"},"IssueSeverity":{"type":"string","enum":["low","medium","high"],"title":"IssueSeverity"},"IssueStatus":{"type":"string","enum":["open","resolved","muted","regressed"],"title":"IssueStatus"},"IssueUpdate":{"properties":{"status":{"anyOf":[{"$ref":"#/components/schemas/IssueStatus"},{"type":"null"}]},"mute_until":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Mute Until"}},"type":"object","title":"IssueUpdate","description":"Triage actions. Exactly one of these is meaningful per call.\n\n`mute_until` implements the plan's archive-until semantics: it pauses\nNOTIFICATION, never detection — the engine keeps tracking the slice, so the\ntimeline stays complete and an escalation can still be recognised."},"LabPoint":{"properties":{"ts":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ts"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"},"lcp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lcp"},"fcp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fcp"},"cls":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cls"},"inp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inp"},"ttfb":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ttfb"}},"type":"object","required":["ts","score","lcp","fcp","cls","inp","ttfb"],"title":"LabPoint","description":"One CS analysis run (sparse). Score is the CS sum; CWV are ms (cls unitless),\nparsed from that run's scores[]."},"LabVsFieldResponse":{"properties":{"page_id":{"type":"string","format":"uuid","title":"Page Id"},"url":{"type":"string","title":"Url"},"window_days":{"type":"integer","title":"Window Days"},"devices":{"items":{"$ref":"#/components/schemas/DeviceComparison"},"type":"array","title":"Devices"}},"type":"object","required":["page_id","url","window_days","devices"],"title":"LabVsFieldResponse"},"LighthouseOpportunity":{"properties":{"id":{"type":"string","title":"Id"},"title":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Title"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"},"savings_ms":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Savings Ms"}},"type":"object","required":["id","title","score","savings_ms"],"title":"LighthouseOpportunity"},"LighthouseReportResponse":{"properties":{"page_id":{"type":"string","format":"uuid","title":"Page Id"},"device":{"type":"string","title":"Device"},"lighthouse_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lighthouse Version"},"fetched_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Fetched Url"},"categories":{"additionalProperties":{"anyOf":[{"type":"number"},{"type":"null"}]},"type":"object","title":"Categories"},"metrics":{"additionalProperties":{"anyOf":[{"type":"number"},{"type":"null"}]},"type":"object","title":"Metrics"},"opportunities":{"items":{"$ref":"#/components/schemas/LighthouseOpportunity"},"type":"array","title":"Opportunities"},"audits":{"additionalProperties":true,"type":"object","title":"Audits"}},"type":"object","required":["page_id","device","lighthouse_version","fetched_url","categories","metrics","opportunities","audits"],"title":"LighthouseReportResponse","description":"Curated Lighthouse report: category scores, metrics (ms), opportunities, and\na whitelist of native Lighthouse audit objects (waterfall / third-party /\nresource-summary / filmstrip / main-thread) for the frontend to render."},"LighthouseSummaryResponse":{"properties":{"page_id":{"type":"string","format":"uuid","title":"Page Id"},"analysis_uuid":{"type":"string","title":"Analysis Uuid"},"device":{"type":"string","title":"Device"},"language":{"type":"string","title":"Language"},"summary":{"type":"string","title":"Summary"},"cached":{"type":"boolean","title":"Cached"}},"type":"object","required":["page_id","analysis_uuid","device","language","summary","cached"],"title":"LighthouseSummaryResponse","description":"AI-generated summary of a Lighthouse run (one device + language). Persisted and\nreused — `cached=false` means it was generated on this request."},"LoAFItem":{"properties":{"duration":{"type":"number","title":"Duration","description":"Frame duration in ms"},"script_url":{"type":"string","title":"Script Url","description":"Primary script URL"},"count":{"type":"integer","title":"Count","description":"Number of occurrences"}},"type":"object","required":["duration","script_url","count"],"title":"LoAFItem","description":"Single long animation frame."},"LoAFRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"limit":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Limit","description":"Max LoAF entries to return","default":10}},"additionalProperties":false,"type":"object","required":["time_range"],"title":"LoAFRequest","description":"Request for Long Animation Frames data."},"LoAFResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/LoAFItem"},"type":"array","title":"Data","description":"Long animation frames"},"total_frames":{"type":"integer","title":"Total Frames","description":"Total long frames"},"avg_duration":{"type":"number","title":"Avg Duration","description":"Average frame duration"},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time"}},"type":"object","required":["data","total_frames","avg_duration","execution_time_ms"],"title":"LoAFResponse","description":"Response for Long Animation Frames data."},"MapDimension":{"properties":{"map":{"type":"string","title":"Map","description":"Map column name (e.g. 'third_parties')"}},"additionalProperties":false,"type":"object","required":["map"],"title":"MapDimension","description":"Group by the keys of a Map column (ARRAY JOIN mapKeys / mapValues).\n\nExample: `{\"map\": \"third_parties\"}` produces one row per (beacon, domain)\nwith `third_parties_key` (the domain) as the dimension and an\nauto-emitted `<map>_total` metric (sum of map values across the group)."},"MapMetric":{"properties":{"map":{"type":"string","title":"Map","description":"Map column name (e.g. 'resource_sizes')"},"key":{"type":"string","maxLength":128,"minLength":1,"pattern":"^[a-zA-Z0-9._-]+$","title":"Key","description":"Map key to extract. Restricted to [a-zA-Z0-9._-] to keep the bracket expression SQL-safe; covers resource types, category names, and sanitized hostnames."}},"additionalProperties":false,"type":"object","required":["map","key"],"title":"MapMetric","description":"Aggregate a single key from a Map column. Behaves like a flat metric:\nthe request's `aggregations` list (sum / avg / p75 / …) is applied to\n`<map>['<key>']` directly, no ARRAY JOIN required.\n\nExample: `{\"map\": \"resource_sizes\", \"key\": \"script\"}` aggregates the\nper-beacon `resource_sizes['script']` value."},"MemberAdd":{"properties":{"email":{"type":"string","format":"email","title":"Email"}},"type":"object","required":["email"],"title":"MemberAdd"},"MemberResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"user_id":{"type":"string","format":"uuid","title":"User Id"},"email":{"type":"string","title":"Email"},"full_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Full Name"},"role":{"$ref":"#/components/schemas/Role"},"totp_enabled":{"type":"boolean","title":"Totp Enabled","default":false},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","user_id","email","full_name","role","created_at"],"title":"MemberResponse"},"Message":{"properties":{"message":{"type":"string","title":"Message"}},"type":"object","required":["message"],"title":"Message"},"MetadataResponse":{"properties":{"metrics":{"items":{"$ref":"#/components/schemas/MetricMeta"},"type":"array","title":"Metrics"},"aggregations":{"items":{"type":"string"},"type":"array","title":"Aggregations"},"dimensions":{"items":{"type":"string"},"type":"array","title":"Dimensions"},"window_options_seconds":{"items":{"type":"integer"},"type":"array","title":"Window Options Seconds"}},"type":"object","required":["metrics","aggregations","dimensions","window_options_seconds"],"title":"MetadataResponse"},"MetricComparison":{"properties":{"metric":{"type":"string","title":"Metric"},"lab_value":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lab Value"},"field_p75":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Field P75"},"verdict":{"type":"string","title":"Verdict"}},"type":"object","required":["metric","lab_value","field_p75","verdict"],"title":"MetricComparison","description":"One CWV metric, lab (CS) vs field (RUM p75), in canonical ms (cls unitless)."},"MetricMeta":{"properties":{"name":{"type":"string","title":"Name"},"label":{"type":"string","title":"Label"},"unit":{"anyOf":[{"type":"string","enum":["ms","score","count","bytes","rate","percent"]},{"type":"null"}],"title":"Unit"},"supported_aggregations":{"items":{"type":"string"},"type":"array","title":"Supported Aggregations"}},"type":"object","required":["name","label","supported_aggregations"],"title":"MetricMeta"},"MetricRange":{"properties":{"metric":{"type":"string","title":"Metric","description":"Metric column — allowlisted (lcp/inp/cls/error_count/…)"},"gte":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Gte","description":"Keep rows with metric >= this"},"lte":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lte","description":"Keep rows with metric <= this"}},"additionalProperties":false,"type":"object","required":["metric"],"title":"MetricRange","description":"A numeric threshold filter on ONE beacon metric (e.g. `{metric:'lcp', gte:2500}`\nfor slow-LCP pageviews, or `{metric:'error_count', gte:1}` = \"has errors\").\nAt least one bound required. NULL metric values don't match (a softnav with no\nLCP isn't a \"slow-LCP\" pageview) — true for the Nullable columns. Note:\n`fetch_xhr_total_calls`/`_total_errors` are non-nullable (0-default), so an\n`lte` on those matches genuine-zero rows."},"MetricValue":{"properties":{"metric":{"type":"string","title":"Metric","description":"Metric name"},"aggregation":{"$ref":"#/components/schemas/AggregationType","description":"Aggregation type"},"value":{"anyOf":[{"type":"number"},{"type":"integer"},{"type":"null"}],"title":"Value","description":"Aggregated value"}},"type":"object","required":["metric","aggregation","value"],"title":"MetricValue","description":"Single metric with its aggregation result."},"Operator":{"type":"string","enum":["gt","gte","lt","lte"],"title":"Operator"},"OrderBy":{"properties":{"field":{"type":"string","title":"Field","description":"Field to sort by (metric name or dimension)"},"direction":{"$ref":"#/components/schemas/SortDirection","description":"Sort direction","default":"desc"}},"type":"object","required":["field"],"title":"OrderBy","description":"Sort configuration for results."},"OrgSiteStatusItem":{"properties":{"beacons_today":{"type":"integer","title":"Beacons Today"},"beacons_per_minute":{"type":"number","title":"Beacons Per Minute"},"last_beacon_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Beacon At"},"site_id":{"type":"string","format":"uuid","title":"Site Id"}},"type":"object","required":["beacons_today","beacons_per_minute","site_id"],"title":"OrgSiteStatusItem","description":"One site's beacon status within the org-wide status listing.\n\nSame fields as `SiteStatusResponse` plus the `site_id` the row belongs to,\nso a single call can back the dashboard header widget across every site."},"OrganizationCreate":{"properties":{"name":{"type":"string","title":"Name"}},"type":"object","required":["name"],"title":"OrganizationCreate"},"OrganizationResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"name":{"type":"string","title":"Name"},"is_active":{"type":"boolean","title":"Is Active"},"is_approved":{"type":"boolean","title":"Is Approved"},"storage":{"$ref":"#/components/schemas/Storage"},"clickhouse_table":{"type":"string","title":"Clickhouse Table"},"plan":{"$ref":"#/components/schemas/Plan"},"is_partner":{"type":"boolean","title":"Is Partner"},"ai_enabled":{"type":"boolean","title":"Ai Enabled"},"synthetic_enabled":{"type":"boolean","title":"Synthetic Enabled"}},"type":"object","required":["id","name","is_active","is_approved","storage","clickhouse_table","plan","is_partner","ai_enabled","synthetic_enabled"],"title":"OrganizationResponse"},"OrganizationUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"ai_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Ai Enabled"},"synthetic_enabled":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Synthetic Enabled"}},"type":"object","title":"OrganizationUpdate"},"OwnershipTransferRequest":{"properties":{"new_owner_user_id":{"type":"string","format":"uuid","title":"New Owner User Id"}},"type":"object","required":["new_owner_user_id"],"title":"OwnershipTransferRequest"},"PageSparkline":{"properties":{"page_id":{"type":"string","format":"uuid","title":"Page Id"},"url":{"type":"string","title":"Url"},"run_count":{"type":"integer","title":"Run Count"},"latest_desktop_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latest Desktop Score"},"latest_mobile_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Latest Mobile Score"},"series":{"items":{"$ref":"#/components/schemas/SparklinePoint"},"type":"array","title":"Series"}},"type":"object","required":["page_id","url","run_count","latest_desktop_score","latest_mobile_score","series"],"title":"PageSparkline","description":"A page's overview: total run count + recent per-run scores for a mini graph,\nplus its latest score per device. Built live from the 1h-cached series."},"PaginatedResponse_ApplicationResponse_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/ApplicationResponse"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[ApplicationResponse]"},"PaginatedResponse_AuditLogEntry_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/AuditLogEntry"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[AuditLogEntry]"},"PaginatedResponse_InviteResponse_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/InviteResponse"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[InviteResponse]"},"PaginatedResponse_IssueResponse_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/IssueResponse"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[IssueResponse]"},"PaginatedResponse_MemberResponse_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/MemberResponse"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[MemberResponse]"},"PaginatedResponse_OrganizationResponse_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/OrganizationResponse"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[OrganizationResponse]"},"PaginatedResponse_PartnerClientResponse_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/PartnerClientResponse"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[PartnerClientResponse]"},"PaginatedResponse_ReleaseResponse_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/ReleaseResponse"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[ReleaseResponse]"},"PaginatedResponse_RuleResponse_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/RuleResponse"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[RuleResponse]"},"PaginatedResponse_SendResponse_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/SendResponse"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[SendResponse]"},"PaginatedResponse_SiteResponse_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/SiteResponse"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[SiteResponse]"},"PaginatedResponse_SyntheticPageListItem_":{"properties":{"data":{"items":{"$ref":"#/components/schemas/SyntheticPageListItem"},"type":"array","title":"Data"},"meta":{"$ref":"#/components/schemas/PaginationMeta"}},"type":"object","required":["data","meta"],"title":"PaginatedResponse[SyntheticPageListItem]"},"PaginationMeta":{"properties":{"total":{"type":"integer","title":"Total"},"limit":{"type":"integer","title":"Limit"},"offset":{"type":"integer","title":"Offset"},"has_more":{"type":"boolean","title":"Has More"}},"type":"object","required":["total","limit","offset","has_more"],"title":"PaginationMeta"},"PartnerAccessResponse":{"properties":{"partner_org_id":{"type":"string","format":"uuid","title":"Partner Org Id"},"partner_org_name":{"type":"string","title":"Partner Org Name"},"billing":{"type":"boolean","title":"Billing"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["partner_org_id","partner_org_name","billing","created_at"],"title":"PartnerAccessResponse","description":"A partner organization that has access to this (client) org.\n\nThe client-side view of the `partners` relationship — \"who manages us\" —\nas opposed to PartnerClientResponse, which is the partner's view of \"our\nclients\". Lets a client org see, and decide to revoke, the partner access\ngranted over it."},"PartnerClientCreate":{"properties":{"name":{"type":"string","title":"Name","description":"Name of the new client organization"},"billing":{"type":"boolean","title":"Billing","description":"Whether this partner handles billing","default":false},"owner_email":{"anyOf":[{"type":"string","format":"email"},{"type":"null"}],"title":"Owner Email","description":"Optional: invite this email as OWNER of the new client org. Sends an invite email; on accept the customer takes ownership. Omit to keep the org partner-managed (headless)."}},"additionalProperties":false,"type":"object","required":["name"],"title":"PartnerClientCreate","description":"Create a new organization and link it to this partner as a client.\n\nSelf-service counterpart to the admin-only link endpoint\n(`POST /admin/partners`, which attaches an *existing* org)."},"PartnerClientResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"partner_org_id":{"type":"string","format":"uuid","title":"Partner Org Id"},"client_org_id":{"type":"string","format":"uuid","title":"Client Org Id"},"client_org_name":{"type":"string","title":"Client Org Name"},"billing":{"type":"boolean","title":"Billing"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","partner_org_id","client_org_id","client_org_name","billing","created_at"],"title":"PartnerClientResponse","description":"A partner-client relationship."},"PartnerClientUsage":{"properties":{"org_id":{"type":"string","format":"uuid","title":"Org Id"},"org_name":{"type":"string","title":"Org Name"},"beacons":{"type":"integer","title":"Beacons"}},"type":"object","required":["org_id","org_name","beacons"],"title":"PartnerClientUsage","description":"Usage for a single client org."},"PartnerUsageResponse":{"properties":{"total_beacons":{"type":"integer","title":"Total Beacons"},"period_start":{"type":"string","format":"date-time","title":"Period Start"},"period_end":{"type":"string","format":"date-time","title":"Period End"},"clients":{"items":{"$ref":"#/components/schemas/PartnerClientUsage"},"type":"array","title":"Clients"}},"type":"object","required":["total_beacons","period_start","period_end","clients"],"title":"PartnerUsageResponse","description":"Aggregated usage across all partner clients."},"Plan":{"type":"string","enum":["beta","starter","pro","partner","enterprise"],"title":"Plan","description":"Subscription plan for organization."},"PresetActionTemplate":{"properties":{"type":{"$ref":"#/components/schemas/ActionType"},"config":{"additionalProperties":true,"type":"object","title":"Config"}},"type":"object","required":["type","config"],"title":"PresetActionTemplate"},"PresetResponse":{"properties":{"id":{"type":"string","title":"Id"},"name":{"type":"string","title":"Name"},"description":{"type":"string","title":"Description"},"rule":{"additionalProperties":true,"type":"object","title":"Rule"},"default_actions":{"items":{"$ref":"#/components/schemas/PresetActionTemplate"},"type":"array","title":"Default Actions"}},"type":"object","required":["id","name","description","rule","default_actions"],"title":"PresetResponse"},"ReleaseCreate":{"properties":{"version":{"type":"string","maxLength":255,"title":"Version"},"released_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Released At"}},"additionalProperties":false,"type":"object","required":["version"],"title":"ReleaseCreate"},"ReleaseResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"application_id":{"type":"string","format":"uuid","title":"Application Id"},"organization_id":{"type":"string","format":"uuid","title":"Organization Id"},"version":{"type":"string","title":"Version"},"released_at":{"type":"string","format":"date-time","title":"Released At"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","application_id","organization_id","version","released_at","created_at"],"title":"ReleaseResponse"},"ReleaseUpdate":{"properties":{"version":{"anyOf":[{"type":"string","maxLength":255},{"type":"null"}],"title":"Version"},"released_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Released At"}},"additionalProperties":false,"type":"object","title":"ReleaseUpdate"},"ResourceBreakdownRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"}},"additionalProperties":false,"type":"object","required":["time_range"],"title":"ResourceBreakdownRequest","description":"Request for resource breakdown by type."},"ResourceBreakdownResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/ResourceTypeItem"},"type":"array","title":"Data","description":"Resource types with data"},"total_size":{"type":"integer","title":"Total Size","description":"Total size across all types"},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time"}},"type":"object","required":["data","total_size","execution_time_ms"],"title":"ResourceBreakdownResponse","description":"Response for resource breakdown."},"ResourceTypeItem":{"properties":{"resource_type":{"type":"string","title":"Resource Type","description":"Resource type (script, css, img, font, other)"},"total_size":{"type":"integer","title":"Total Size","description":"Total size in bytes"},"total_count":{"type":"integer","title":"Total Count","description":"Total resource count"},"avg_duration":{"type":"number","title":"Avg Duration","description":"Average duration in ms"},"percentage":{"type":"number","title":"Percentage","description":"Percentage of total size"}},"type":"object","required":["resource_type","total_size","total_count","avg_duration","percentage"],"title":"ResourceTypeItem","description":"Single resource type with aggregated data."},"ResultDevice":{"properties":{"average":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Average"},"error":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Error"},"vitals":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Vitals"},"pages":{"additionalProperties":{"$ref":"#/components/schemas/ResultPage"},"type":"object","title":"Pages"}},"type":"object","title":"ResultDevice"},"ResultPage":{"properties":{"page_url":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Page Url"},"error":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Error"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"},"scores":{"items":{"$ref":"#/components/schemas/ScoreEntry"},"type":"array","title":"Scores"}},"type":"object","title":"ResultPage","description":"One page's result. Asset URLs (screenshot / lighthouse) are intentionally\nomitted — reach the screenshot only via the access-controlled proxy."},"ResultTtfbPhase":{"properties":{"range_dns":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Dns"},"range_connection":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Connection"},"range_ssl":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Ssl"},"range_server":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Server"},"range_transfer":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Transfer"},"total":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total"}},"type":"object","title":"ResultTtfbPhase"},"Role":{"type":"string","enum":["owner","member"],"title":"Role","description":"Role for organization members."},"RuleCreate":{"properties":{"name":{"type":"string","maxLength":100,"minLength":1,"title":"Name"},"is_active":{"type":"boolean","title":"Is Active","default":true},"scope_type":{"$ref":"#/components/schemas/ScopeType"},"site_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Site Id"},"tag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"},"metric":{"type":"string","title":"Metric"},"aggregation":{"type":"string","title":"Aggregation"},"identity":{"anyOf":[{"type":"string","enum":["stitch","session"]},{"type":"null"}],"title":"Identity"},"operator":{"$ref":"#/components/schemas/Operator"},"condition_type":{"$ref":"#/components/schemas/ConditionType"},"threshold":{"type":"number","title":"Threshold"},"window_seconds":{"type":"integer","title":"Window Seconds"},"baseline_window_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Baseline Window Seconds"},"filters":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Filters"},"re_notify_after_seconds":{"anyOf":[{"type":"integer","minimum":3600.0},{"type":"null"}],"title":"Re Notify After Seconds"},"actions":{"items":{"$ref":"#/components/schemas/ActionCreate"},"type":"array","maxItems":10,"minItems":1,"title":"Actions"}},"type":"object","required":["name","scope_type","metric","aggregation","operator","condition_type","threshold","window_seconds","actions"],"title":"RuleCreate"},"RuleResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"organization_id":{"type":"string","format":"uuid","title":"Organization Id"},"name":{"type":"string","title":"Name"},"is_active":{"type":"boolean","title":"Is Active"},"scope_type":{"$ref":"#/components/schemas/ScopeType"},"site_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Site Id"},"tag":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Tag"},"metric":{"type":"string","title":"Metric"},"aggregation":{"type":"string","title":"Aggregation"},"identity":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Identity"},"operator":{"$ref":"#/components/schemas/Operator"},"condition_type":{"$ref":"#/components/schemas/ConditionType"},"threshold":{"type":"number","title":"Threshold"},"window_seconds":{"type":"integer","title":"Window Seconds"},"baseline_window_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Baseline Window Seconds"},"filters":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Filters"},"re_notify_after_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Re Notify After Seconds"},"last_evaluated_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Evaluated At"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"updated_at":{"type":"string","format":"date-time","title":"Updated At"},"actions":{"items":{"$ref":"#/components/schemas/ActionResponse"},"type":"array","title":"Actions"}},"type":"object","required":["id","organization_id","name","is_active","scope_type","site_id","tag","metric","aggregation","identity","operator","condition_type","threshold","window_seconds","baseline_window_seconds","filters","re_notify_after_seconds","last_evaluated_at","created_at","updated_at","actions"],"title":"RuleResponse"},"RuleUpdate":{"properties":{"name":{"anyOf":[{"type":"string","maxLength":100,"minLength":1},{"type":"null"}],"title":"Name"},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"threshold":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Threshold"},"window_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Window Seconds"},"baseline_window_seconds":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Baseline Window Seconds"},"operator":{"anyOf":[{"$ref":"#/components/schemas/Operator"},{"type":"null"}]},"re_notify_after_seconds":{"anyOf":[{"type":"integer","minimum":3600.0},{"type":"null"}],"title":"Re Notify After Seconds"},"filters":{"anyOf":[{"additionalProperties":true,"type":"object"},{"type":"null"}],"title":"Filters"},"actions":{"anyOf":[{"items":{"$ref":"#/components/schemas/ActionUpdate"},"type":"array","maxItems":10},{"type":"null"}],"title":"Actions"}},"type":"object","title":"RuleUpdate"},"ScopeType":{"type":"string","enum":["site","tag"],"title":"ScopeType"},"ScoreEntry":{"properties":{"name":{"type":"string","title":"Name"},"value":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Value"},"score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Score"}},"type":"object","required":["name"],"title":"ScoreEntry"},"SendResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"rule_id":{"type":"string","format":"uuid","title":"Rule Id"},"site_id":{"type":"string","format":"uuid","title":"Site Id"},"sent_at":{"type":"string","format":"date-time","title":"Sent At"},"metric_value":{"type":"number","title":"Metric Value"},"context":{"additionalProperties":true,"type":"object","title":"Context"},"delivery_log":{"items":{},"type":"array","title":"Delivery Log"}},"type":"object","required":["id","rule_id","site_id","sent_at","metric_value","context","delivery_log"],"title":"SendResponse"},"ServerTimingCacheItem":{"properties":{"layer":{"type":"string","title":"Layer","description":"cdn | origin"},"status":{"type":"string","title":"Status","description":"Normalized cache status (HIT/MISS/...)"},"count":{"type":"integer","title":"Count","description":"Pageviews with this status"}},"type":"object","required":["layer","status","count"],"title":"ServerTimingCacheItem","description":"Cache-status distribution for one layer."},"ServerTimingKeyItem":{"properties":{"key":{"type":"string","title":"Key","description":"Server-Timing key (catalog or custom)"},"count":{"type":"integer","title":"Count","description":"Pageviews carrying this key"},"p75_ms":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P75 Ms","description":"p75 of the key's duration"}},"type":"object","required":["key","count"],"title":"ServerTimingKeyItem","description":"One Tier-2/3 custom key from server_timing_dur."},"ServerTimingPhaseItem":{"properties":{"phase":{"type":"string","title":"Phase","description":"edge_dur/origin_dur/backend_dur/db_dur/cache_dur/external_dur/render_dur"},"p50":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P50"},"p75":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P75"},"p95":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"P95"}},"type":"object","required":["phase"],"title":"ServerTimingPhaseItem","description":"Percentiles of one backend-phase duration (ms)."},"ServerTimingRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","description":"Max custom keys (top_keys block)","default":20}},"additionalProperties":false,"type":"object","required":["time_range"],"title":"ServerTimingRequest","description":"Request for the Server-Timing dashboard panel."},"ServerTimingResponse":{"properties":{"cache":{"items":{"$ref":"#/components/schemas/ServerTimingCacheItem"},"type":"array","title":"Cache","description":"Cache-status distribution"},"phases":{"items":{"$ref":"#/components/schemas/ServerTimingPhaseItem"},"type":"array","title":"Phases","description":"Backend-phase percentiles"},"top_keys":{"items":{"$ref":"#/components/schemas/ServerTimingKeyItem"},"type":"array","title":"Top Keys","description":"Top custom keys by p75"},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time"}},"type":"object","required":["cache","phases","top_keys","execution_time_ms"],"title":"ServerTimingResponse","description":"Response for the Server-Timing dashboard panel: three blocks."},"SessionConsent":{"type":"string","enum":["deferred","immediate"],"title":"SessionConsent","description":"When the served bundle writes the session identifier under consent (only\nmeaningful when `collect_sessions` is on).\n\nDEFERRED  — defer the session write until `window.fastmon.grantConsent()` is\n            called (consent-first; the privacy-safe default).\nIMMEDIATE — write the session on load (consent already handled / not required)."},"SiteCreate":{"properties":{"application_id":{"type":"string","format":"uuid","title":"Application Id"},"name":{"type":"string","title":"Name"},"domain":{"type":"string","title":"Domain"},"data_retention_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Data Retention Days"},"store_stitch":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Store Stitch"},"count_visitors_by":{"anyOf":[{"$ref":"#/components/schemas/VisitorIdentity"},{"type":"null"}]},"tags":{"items":{"type":"string"},"type":"array","maxItems":10,"title":"Tags","default":[]}},"type":"object","required":["application_id","name","domain"],"title":"SiteCreate","description":"Create a site (a domain / analytics unit) under an existing application.\n\nA site is pure domain/analytics; the embed + all collection config live on the\napplication (`application_id`, required). Only the domain, a display name, tags,\nand the three per-domain overrides are set here. Each override is NULL by\ndefault = inherit the application's value; a non-null value overrides it."},"SitePolicy":{"type":"string","enum":["open","auto","strict"],"title":"SitePolicy","description":"How an application handles an UNKNOWN beacon hostname (one with no matching\nregistered Site). Replaces the old `auto_provision_sites` flag and the per-Site\n`enforce_domain_match`.\n\nOPEN   — record a discovery suggestion, drop the beacon (default).\nAUTO   — auto-create a Site for the hostname.\nSTRICT — drop; no suggestion, no auto-provision, no one-site lenient bind\n         (only exactly-registered domains are served)."},"SiteResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"organization_id":{"type":"string","format":"uuid","title":"Organization Id"},"application_id":{"type":"string","format":"uuid","title":"Application Id"},"name":{"type":"string","title":"Name"},"domain":{"type":"string","title":"Domain"},"is_active":{"type":"boolean","title":"Is Active"},"tags":{"items":{"type":"string"},"type":"array","title":"Tags","default":[]},"data_retention_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Data Retention Days"},"store_stitch":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Store Stitch"},"count_visitors_by":{"anyOf":[{"$ref":"#/components/schemas/VisitorIdentity"},{"type":"null"}]}},"type":"object","required":["id","organization_id","application_id","name","domain","is_active"],"title":"SiteResponse","description":"A site: a pure domain / analytics unit belonging to one application.\n\nThe embed + collection config live on the application (fetch it via\n`application_id`); they are NOT mirrored here. The three per-domain fields are\nreturned RAW: NULL = inherits the application's default, a non-null value\noverrides it (the FE resolves the effective value against the application)."},"SiteStatusResponse":{"properties":{"beacons_today":{"type":"integer","title":"Beacons Today"},"beacons_per_minute":{"type":"number","title":"Beacons Per Minute"},"last_beacon_at":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}],"title":"Last Beacon At"}},"type":"object","required":["beacons_today","beacons_per_minute"],"title":"SiteStatusResponse"},"SiteUpdate":{"properties":{"name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Name"},"domain":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Domain"},"data_retention_days":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Data Retention Days"},"store_stitch":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Store Stitch"},"count_visitors_by":{"anyOf":[{"$ref":"#/components/schemas/VisitorIdentity"},{"type":"null"}]},"is_active":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Is Active"},"tags":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":10},{"type":"null"}],"title":"Tags"}},"type":"object","title":"SiteUpdate"},"SiteUsage":{"properties":{"site_id":{"type":"string","format":"uuid","title":"Site Id"},"site_name":{"type":"string","title":"Site Name"},"beacon_count":{"type":"integer","title":"Beacon Count"}},"type":"object","required":["site_id","site_name","beacon_count"],"title":"SiteUsage"},"SortDirection":{"type":"string","enum":["asc","desc"],"title":"SortDirection","description":"Sort order direction."},"SparklinePoint":{"properties":{"ts":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ts"},"desktop_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Desktop Score"},"mobile_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Mobile Score"}},"type":"object","title":"SparklinePoint","description":"One run's score in a sparkline series (newest first). CS scores are sums →\nfloat-safe."},"Storage":{"type":"string","enum":["shared","dedicated","external"],"title":"Storage","description":"Storage mode for organization data."},"SyntheticAnalysisStatus":{"properties":{"analysis_uuid":{"type":"string","title":"Analysis Uuid"},"status":{"type":"integer","title":"Status"},"percent":{"type":"integer","title":"Percent"},"done":{"type":"boolean","title":"Done"}},"type":"object","required":["analysis_uuid","status","percent","done"],"title":"SyntheticAnalysisStatus","description":"Progress of an in-flight analysis (for run UX)."},"SyntheticPageCreate":{"properties":{"url":{"type":"string","maxLength":2048,"title":"Url"},"mode":{"type":"string","enum":["monitor","oneshot"],"title":"Mode","default":"monitor"},"schedule":{"type":"boolean","title":"Schedule","default":true},"ttfb_schedule":{"type":"boolean","title":"Ttfb Schedule","default":true},"nocache":{"type":"boolean","title":"Nocache","default":true}},"type":"object","required":["url"],"title":"SyntheticPageCreate","description":"Create a synthetic page. The URL is normalized to the beacon form and must be\nunder the site's own domain. Registering always runs one immediate analysis.\n\n`mode` picks the intent:\n- `monitor` (default): a sticky, quota-counted page. `schedule` (recurring 24h\n  Lighthouse, default on) and `ttfb_schedule` (recurring 5-min CS, default on) are\n  honored — set either false to register paused / opt out; the flags govern only\n  the *recurring* runs.\n- `oneshot`: an unbudgeted \"measure now\". The schedule flags are ignored (both\n  forced off), `nocache` is forced true (fresh origin fetch), and the single\n  creation run is mandatory — a missing run id is a hard 502, not tolerated."},"SyntheticPageCreateResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"site_id":{"type":"string","format":"uuid","title":"Site Id"},"url":{"type":"string","title":"Url"},"source":{"$ref":"#/components/schemas/SyntheticPageSource"},"auto_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Rank"},"cs_site_uuid":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Cs Site Uuid"},"schedule":{"type":"boolean","title":"Schedule"},"ttfb_schedule":{"type":"boolean","title":"Ttfb Schedule"},"nocache":{"type":"boolean","title":"Nocache"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"analysis_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Analysis Uuid"},"analysis_status":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Analysis Status"}},"type":"object","required":["id","site_id","url","source","auto_rank","cs_site_uuid","schedule","ttfb_schedule","nocache","created_at"],"title":"SyntheticPageCreateResponse","description":"A created/registered page plus the run that creation always triggers.\n\nCreating a CS site kicks off one immediate analysis regardless of the schedule\nflags — the flags gate only the *recurring* runs, so even a page created paused\n(`schedule=false`) produces this one creation run. Both manual create and one-shot\nsurface its `analysis_uuid` for the client to poll, instead of firing a redundant\nsecond run. `analysis_uuid` is null only if CS registered the site but returned\nno run id (manual create tolerates that; one-shot 502s)."},"SyntheticPageListItem":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"site_id":{"type":"string","format":"uuid","title":"Site Id"},"url":{"type":"string","title":"Url"},"source":{"$ref":"#/components/schemas/SyntheticPageSource"},"auto_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Rank"},"cs_site_uuid":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Cs Site Uuid"},"schedule":{"type":"boolean","title":"Schedule"},"ttfb_schedule":{"type":"boolean","title":"Ttfb Schedule"},"nocache":{"type":"boolean","title":"Nocache"},"created_at":{"type":"string","format":"date-time","title":"Created At"},"summary":{"anyOf":[{"$ref":"#/components/schemas/SyntheticPageSummary"},{"type":"null"}]}},"type":"object","required":["id","site_id","url","source","auto_rank","cs_site_uuid","schedule","ttfb_schedule","nocache","created_at"],"title":"SyntheticPageListItem","description":"A page plus an optional last-result summary (populated when `summary=true`)."},"SyntheticPageResponse":{"properties":{"id":{"type":"string","format":"uuid","title":"Id"},"site_id":{"type":"string","format":"uuid","title":"Site Id"},"url":{"type":"string","title":"Url"},"source":{"$ref":"#/components/schemas/SyntheticPageSource"},"auto_rank":{"anyOf":[{"type":"integer"},{"type":"null"}],"title":"Auto Rank"},"cs_site_uuid":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Cs Site Uuid"},"schedule":{"type":"boolean","title":"Schedule"},"ttfb_schedule":{"type":"boolean","title":"Ttfb Schedule"},"nocache":{"type":"boolean","title":"Nocache"},"created_at":{"type":"string","format":"date-time","title":"Created At"}},"type":"object","required":["id","site_id","url","source","auto_rank","cs_site_uuid","schedule","ttfb_schedule","nocache","created_at"],"title":"SyntheticPageResponse"},"SyntheticPageSource":{"type":"string","enum":["manual","auto","oneshot"],"title":"SyntheticPageSource","description":"How a synthetic page was added."},"SyntheticPageSummary":{"properties":{"last_run_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Last Run At"},"desktop_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Desktop Score"},"mobile_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Mobile Score"}},"type":"object","required":["last_run_at","desktop_score","mobile_score"],"title":"SyntheticPageSummary","description":"Compact last-result health snapshot for list rows (avoids the N+1 of\nfetching results per page from the client)."},"SyntheticPageUpdate":{"properties":{"schedule":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Schedule"},"ttfb_schedule":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Ttfb Schedule"},"nocache":{"anyOf":[{"type":"boolean"},{"type":"null"}],"title":"Nocache"}},"type":"object","title":"SyntheticPageUpdate","description":"Patch monitoring config. All optional; only provided fields change.\n`schedule=false` pauses the recurring Lighthouse run — the page stays and is\nstill runnable on demand. `nocache` toggles CS cache-bypass for future runs."},"SyntheticQuota":{"properties":{"manual_used":{"type":"integer","title":"Manual Used"},"manual_limit":{"type":"integer","title":"Manual Limit"},"auto_used":{"type":"integer","title":"Auto Used"},"auto_limit":{"type":"integer","title":"Auto Limit"}},"type":"object","required":["manual_used","manual_limit","auto_used","auto_limit"],"title":"SyntheticQuota","description":"Org-wide synthetic page budget. Manual and auto pages have independent caps\n(derived from the org plan); one-shots are unbounded and not counted. Usage spans\nALL sites in the org, so it can exceed this site's `page_count`."},"SyntheticResultItem":{"properties":{"analysis_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Analysis Uuid"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"data":{"additionalProperties":{"$ref":"#/components/schemas/ResultDevice"},"type":"object","title":"Data"},"data_ttfb":{"additionalProperties":{"$ref":"#/components/schemas/ResultTtfbPhase"},"type":"object","title":"Data Ttfb"}},"type":"object","title":"SyntheticResultItem"},"SyntheticResultsResponse":{"properties":{"total":{"type":"integer","title":"Total"},"results":{"items":{"$ref":"#/components/schemas/SyntheticResultItem"},"type":"array","title":"Results"}},"type":"object","required":["total","results"],"title":"SyntheticResultsResponse","description":"Shaped synthetic-monitoring result history. Asset URLs are stripped;\nscreenshots come from the proxy endpoint only."},"SyntheticRunListItem":{"properties":{"analysis_uuid":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Analysis Uuid"},"created_at":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Created At"},"desktop_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Desktop Score"},"mobile_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Mobile Score"}},"type":"object","title":"SyntheticRunListItem","description":"One run, trimmed to what a run-selector needs: id + when + per-device score.\nDeliberately omits scores[]/ttfb/curation so the selector payload stays small."},"SyntheticRunResponse":{"properties":{"analysis_uuid":{"type":"string","title":"Analysis Uuid"},"site_uuid":{"type":"string","title":"Site Uuid"},"status":{"type":"integer","title":"Status"}},"type":"object","required":["analysis_uuid","site_uuid","status"],"title":"SyntheticRunResponse","description":"Result of triggering an on-demand analysis."},"SyntheticRunsResponse":{"properties":{"total":{"type":"integer","title":"Total"},"runs":{"items":{"$ref":"#/components/schemas/SyntheticRunListItem"},"type":"array","title":"Runs"}},"type":"object","required":["total","runs"],"title":"SyntheticRunsResponse","description":"Lightweight run list for the run-selector (live from CS)."},"SyntheticSummaryResponse":{"properties":{"site_id":{"type":"string","format":"uuid","title":"Site Id"},"page_count":{"type":"integer","title":"Page Count"},"total_runs":{"type":"integer","title":"Total Runs"},"aggregate_desktop_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Aggregate Desktop Score"},"aggregate_mobile_score":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Aggregate Mobile Score"},"pages":{"items":{"$ref":"#/components/schemas/PageSparkline"},"type":"array","title":"Pages"},"partial":{"type":"boolean","title":"Partial","default":false},"quota":{"$ref":"#/components/schemas/SyntheticQuota"}},"type":"object","required":["site_id","page_count","total_runs","aggregate_desktop_score","aggregate_mobile_score","pages","quota"],"title":"SyntheticSummaryResponse","description":"Site-wide synthetic overview: aggregate latest score across pages, total runs,\nand a per-page sparkline each. Computed live from cached per-page series — no\nstored aggregate (CS stays the system of record)."},"TestSendResponse":{"properties":{"rule_id":{"type":"string","format":"uuid","title":"Rule Id"},"delivery_log":{"items":{"additionalProperties":true,"type":"object"},"type":"array","title":"Delivery Log"}},"type":"object","required":["rule_id","delivery_log"],"title":"TestSendResponse"},"ThirdPartyItem":{"properties":{"domain":{"type":"string","title":"Domain","description":"Third-party domain"},"count":{"type":"integer","title":"Count","description":"Number of occurrences"}},"type":"object","required":["domain","count"],"title":"ThirdPartyItem","description":"Single third-party domain with data."},"ThirdPartyRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"limit":{"type":"integer","maximum":50.0,"minimum":1.0,"title":"Limit","description":"Max domains to return","default":10}},"additionalProperties":false,"type":"object","required":["time_range"],"title":"ThirdPartyRequest","description":"Request for third-party blocking domains."},"ThirdPartyResponse":{"properties":{"data":{"items":{"$ref":"#/components/schemas/ThirdPartyItem"},"type":"array","title":"Data","description":"Third-party domains"},"total_count":{"type":"integer","title":"Total Count","description":"Total third-party resources"},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time"}},"type":"object","required":["data","total_count","execution_time_ms"],"title":"ThirdPartyResponse","description":"Response for third-party blocking domains."},"TimeRange":{"properties":{"from":{"type":"string","format":"date-time","title":"From","description":"Start of time range (inclusive)"},"to":{"type":"string","format":"date-time","title":"To","description":"End of time range (exclusive)"}},"type":"object","required":["from","to"],"title":"TimeRange","description":"Required time range for queries."},"TimeseriesResponse":{"properties":{"page_id":{"type":"string","format":"uuid","title":"Page Id"},"url":{"type":"string","title":"Url"},"device":{"type":"string","title":"Device"},"window_days":{"type":"integer","title":"Window Days"},"interval":{"type":"string","title":"Interval"},"lab":{"items":{"$ref":"#/components/schemas/LabPoint"},"type":"array","title":"Lab"},"ttfb":{"items":{"$ref":"#/components/schemas/TtfbSeriesPoint"},"type":"array","title":"Ttfb"},"field":{"items":{"$ref":"#/components/schemas/FieldPoint"},"type":"array","title":"Field"}},"type":"object","required":["page_id","url","device","window_days","interval","lab","ttfb","field"],"title":"TimeseriesResponse","description":"Series for charting, different time granularities by design: sparse `lab`\npoints (Lighthouse) and raw `ttfb` points (dedicated 5-min schedule) overlaid on\nthe regular `field` p75 line. `lab.ttfb` is Lighthouse's server-only TTFB; the\n`ttfb` series is the full phase breakdown — they are not the same measurement."},"TtfbDiagnosisResponse":{"properties":{"page_id":{"type":"string","format":"uuid","title":"Page Id"},"url":{"type":"string","title":"Url"},"window_days":{"type":"integer","title":"Window Days"},"lab_phases":{"anyOf":[{"$ref":"#/components/schemas/TtfbPhases"},{"type":"null"}]},"devices":{"items":{"$ref":"#/components/schemas/TtfbFieldDevice"},"type":"array","title":"Devices"}},"type":"object","required":["page_id","url","window_days","lab_phases","devices"],"title":"TtfbDiagnosisResponse"},"TtfbFieldDevice":{"properties":{"device":{"type":"string","title":"Device"},"field_ttfb_p75":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Field Ttfb P75"},"field_dns_p75":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Field Dns P75"},"field_tcp_p75":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Field Tcp P75"},"samples":{"type":"integer","title":"Samples"},"sufficient":{"type":"boolean","title":"Sufficient"},"verdict":{"type":"string","title":"Verdict"}},"type":"object","required":["device","field_ttfb_p75","field_dns_p75","field_tcp_p75","samples","sufficient","verdict"],"title":"TtfbFieldDevice"},"TtfbPhases":{"properties":{"range_dns":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Dns"},"range_connection":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Connection"},"range_ssl":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Ssl"},"range_server":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Server"},"range_transfer":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Transfer"},"total":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total"},"server_dominant":{"type":"boolean","title":"Server Dominant"}},"type":"object","required":["range_dns","range_connection","range_ssl","range_server","range_transfer","total","server_dominant"],"title":"TtfbPhases","description":"CS server-side TTFB phase breakdown (ms), once per page (not per device)."},"TtfbSeriesPoint":{"properties":{"ts":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Ts"},"range_dns":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Dns"},"range_connection":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Connection"},"range_ssl":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Ssl"},"range_server":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Server"},"range_transfer":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Range Transfer"},"total":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Total"}},"type":"object","required":["ts","range_dns","range_connection","range_ssl","range_server","range_transfer","total"],"title":"TtfbSeriesPoint","description":"One dedicated TTFB run (5-min schedule): raw DNS→transfer phases + total (ms).\nDevice-independent — CS measures TTFB once per run, not per device."},"UnknownHostnameSuggestion":{"properties":{"hostname":{"type":"string","title":"Hostname"},"hits":{"type":"integer","title":"Hits"},"application_id":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"title":"Application Id"},"application_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Application Name"}},"type":"object","required":["hostname","hits"],"title":"UnknownHostnameSuggestion","description":"A hostname observed hitting an application that matched no registered site —\na candidate to adopt as a new site (one site per domain). The observed value\nis a hostname (`urlparse().hostname`, port-free); the customer registers it as\na `Site.domain`. `application_id`/`application_name` say WHICH application\nobserved it (null only for legacy ephemeral entries recorded before the\napplication dimension existed)."},"UnknownHostnamesResponse":{"properties":{"suggestions":{"items":{"$ref":"#/components/schemas/UnknownHostnameSuggestion"},"type":"array","title":"Suggestions"}},"type":"object","required":["suggestions"],"title":"UnknownHostnamesResponse"},"UsageResponse":{"properties":{"total_beacons":{"type":"integer","title":"Total Beacons"},"period_start":{"type":"string","format":"date-time","title":"Period Start"},"period_end":{"type":"string","format":"date-time","title":"Period End"},"sites":{"items":{"$ref":"#/components/schemas/SiteUsage"},"type":"array","title":"Sites"}},"type":"object","required":["total_beacons","period_start","period_end","sites"],"title":"UsageResponse"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"},"input":{"title":"Input"},"ctx":{"type":"object","title":"Context"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"VisitorAggregateFilters":{"properties":{"min_page_count":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Min Page Count"},"max_page_count":{"anyOf":[{"type":"integer","minimum":1.0},{"type":"null"}],"title":"Max Page Count"},"min_duration_ms":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Min Duration Ms"},"max_duration_ms":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Max Duration Ms"},"min_avg_lcp_ms":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Min Avg Lcp Ms"},"max_avg_lcp_ms":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Max Avg Lcp Ms"},"min_errors":{"anyOf":[{"type":"integer","minimum":0.0},{"type":"null"}],"title":"Min Errors"},"contains_page_type":{"anyOf":[{"type":"string","maxLength":64},{"type":"null"}],"title":"Contains Page Type","description":"Only visitors whose session includes >=1 pageview of this page_type"}},"additionalProperties":false,"type":"object","title":"VisitorAggregateFilters","description":"Post-aggregation filters for `/visitors`.\n\nThese apply AFTER the `GROUP BY` on the resolved identity, so they emit HAVING\nclauses rather than WHERE. Fields are independent; omit any to skip that bound.\nNull `avg_lcp` rows (visitors with no LCP measurements) are excluded from any\n`min_avg_lcp_ms`/`max_avg_lcp_ms` bound."},"VisitorDetailRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"identity":{"anyOf":[{"type":"string","enum":["stitch","session"]},{"type":"null"}],"title":"Identity","description":"Identifier kind for `id`: 'session' or 'stitch'. Null resolves the same way the visitor list does (site's preferred/available identity)."},"id":{"type":"string","minLength":1,"title":"Id","description":"Visitor ID to retrieve (session_id or stitch)"}},"additionalProperties":false,"type":"object","required":["time_range","id"],"title":"VisitorDetailRequest","description":"Request for visitor detail (all page visits)."},"VisitorDetailResponse":{"properties":{"id":{"type":"string","title":"Id","description":"Visitor identifier (stitch hex or session_id)"},"identity":{"type":"string","title":"Identity","description":"Identifier kind for `id`: stitch | session"},"pages":{"items":{"$ref":"#/components/schemas/VisitorPageVisit"},"type":"array","title":"Pages","description":"Chronological page visits"},"execution_time_ms":{"type":"number","title":"Execution Time Ms","description":"Query execution time"}},"type":"object","required":["id","identity","pages","execution_time_ms"],"title":"VisitorDetailResponse","description":"Response for visitor detail query."},"VisitorIdentity":{"type":"string","enum":["stitch","session"],"title":"VisitorIdentity","description":"Which identifier the `visitors` metric defaults to in reports (the\n`count_visitors_by` field). A REPORTING preference, deliberately separate from\nthe store_stitch/collect_sessions COLLECTION flags (those decide whether the\ndata exists at all). The query-time resolver clamps this to what the site\nactually stores, and a per-query `identity` param overrides it. See\nresolve_identity()."},"VisitorPageVisit":{"properties":{"url":{"type":"string","title":"Url","description":"Page URL"},"started_at":{"type":"string","format":"date-time","title":"Started At","description":"Pageview start (wall-clock). Anchor for replay timelines."},"ended_at":{"type":"string","format":"date-time","title":"Ended At","description":"Pageview end (wall-clock): close-out / hidden / terminated moment. Together with `started_at` gives true pageview duration."},"nav_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Nav Type","description":"Navigation type"},"lcp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lcp","description":"Largest Contentful Paint (ms)"},"fcp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Fcp","description":"First Contentful Paint (ms)"},"cls":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Cls","description":"Cumulative Layout Shift"},"inp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inp","description":"Interaction to Next Paint (ms)"},"ttfb":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Ttfb","description":"Time to First Byte (ms)"},"page_load_time":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Page Load Time","description":"Full page load time (ms)"},"cdn_cache_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cdn Cache Status","description":"CDN cache status for this pageview (HIT/MISS/…), if collected"},"origin_cache_status":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Origin Cache Status","description":"Origin cache status for this pageview (HIT/MISS/…), if collected"},"page_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Page Type","description":"Page type for this pageview (product/category/cart/…), if detected"},"cloud_provider":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cloud Provider","description":"Cloud/crawler network label (aws/googlebot/…); null = normal network"},"bot_name":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bot Name","description":"Detected bot slug ('unknown' = generic heuristic); null = no bot signal"},"bot_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Bot Type","description":"Bot category tag (ai-crawler/search-engine/…); null = no bot signal"},"is_cloud_provider":{"type":"boolean","title":"Is Cloud Provider","description":"Derived: cloud_provider is set (datacenter/crawler network)","default":false},"is_bot":{"type":"boolean","title":"Is Bot","description":"Derived: bot_name is set (incl. 'unknown')","default":false},"lcp_ttfb":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lcp Ttfb","description":"LCP phase 1: time to first byte (ms)"},"lcp_load_delay":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lcp Load Delay","description":"LCP phase 2: resource load delay — discovery gap (ms)"},"lcp_load_duration":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lcp Load Duration","description":"LCP phase 3: resource load duration — download (ms)"},"lcp_render_delay":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Lcp Render Delay","description":"LCP phase 4: element render delay (ms)"},"lcp_target":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Lcp Target","description":"CSS selector path of the LCP element, if captured"},"cls_target":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cls Target","description":"CSS selector path of the largest layout shift's element, if captured"},"inp_input_delay":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inp Input Delay","description":"INP subpart: input delay of the reported interaction (ms)"},"inp_processing":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inp Processing","description":"INP subpart: processing duration of the reported interaction (ms)"},"inp_presentation":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Inp Presentation","description":"INP subpart: presentation delay of the reported interaction (ms)"},"inp_interaction_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inp Interaction Type","description":"Reported INP interaction type (pointer/keyboard), if captured"},"inp_target":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Inp Target","description":"CSS selector path of the reported INP interaction's target, if captured"},"error_count":{"type":"integer","title":"Error Count","description":"Errors on this page","default":0},"errors":{"items":{"$ref":"#/components/schemas/BeaconError"},"type":"array","title":"Errors","description":"Structured per-beacon errors (top 5 by occurrence)"}},"type":"object","required":["url","started_at","ended_at"],"title":"VisitorPageVisit","description":"Single page visit within a visitor's activity."},"VisitorSummaryItem":{"properties":{"id":{"type":"string","title":"Id","description":"Visitor identifier (stitch hex or session_id, per `identity`)"},"identity":{"type":"string","title":"Identity","description":"Identifier this row is grouped by: stitch | session"},"started_at":{"type":"string","format":"date-time","title":"Started At","description":"First pageview start for this visitor (wall-clock)"},"ended_at":{"type":"string","format":"date-time","title":"Ended At","description":"Last pageview end for this visitor (wall-clock)"},"duration_ms":{"type":"number","title":"Duration Ms","description":"Span from first to last pageview in milliseconds"},"page_count":{"type":"integer","title":"Page Count","description":"Number of page views"},"country":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Country","description":"Country (ISO code)"},"browser":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Browser","description":"Browser name"},"browser_version":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Browser Version","description":"Browser version"},"device_type":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Device Type","description":"Device type"},"os":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Os","description":"Operating system"},"avg_lcp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Lcp","description":"Average LCP across pages"},"avg_fcp":{"anyOf":[{"type":"number"},{"type":"null"}],"title":"Avg Fcp","description":"Average FCP across pages"},"total_errors":{"type":"integer","title":"Total Errors","description":"Total errors","default":0}},"type":"object","required":["id","identity","started_at","ended_at","duration_ms","page_count"],"title":"VisitorSummaryItem","description":"Summary of a single visitor (grouped by the resolved `identity`)."},"VisitorsListRequest":{"properties":{"time_range":{"$ref":"#/components/schemas/TimeRange","description":"Time range for the query"},"filters":{"$ref":"#/components/schemas/Filters","description":"Optional filters"},"identity":{"anyOf":[{"type":"string","enum":["stitch","session"]},{"type":"null"}],"title":"Identity","description":"Identifier to group visitors by: 'stitch' or 'session'. Null → the per-site default (stitch preferred)."},"visitor_filters":{"$ref":"#/components/schemas/VisitorAggregateFilters","description":"Post-aggregation filters (page count, duration, errors, avg LCP)"},"search":{"anyOf":[{"type":"string","maxLength":100},{"type":"null"}],"title":"Search","description":"Search by visitor ID"},"limit":{"type":"integer","maximum":100.0,"minimum":1.0,"title":"Limit","description":"Max visitors to return","default":50},"cursor":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Cursor","description":"Opaque pagination cursor"}},"additionalProperties":false,"type":"object","required":["time_range"],"title":"VisitorsListRequest","description":"Request for the visitors list.\n\nCursor-paginated; always ordered by (start_time DESC, id DESC). Clients that\nwant to re-sort do so over the loaded rows client-side."}},"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"fm_…","description":"API token generated from the fastmon dashboard (Account → API Token). Send as `Authorization: Bearer fm_...` or paste the full token (including the `fm_` prefix) into the Authorize dialog."}}},"tags":[{"name":"organizations","description":"Manage organizations: the top-level tenant that owns sites, members, and analytics data. Covers organization CRUD, usage summaries, and ownership transfer."},{"name":"members","description":"List and manage members of an organization, including their roles."},{"name":"sites","description":"Manage the sites (domains) monitored under an organization — each a domain/analytics unit belonging to one application. Includes site CRUD, tag- and application-based filtering, per-domain settings, and live beacon-receipt status. (The embed + hash rotation live on the application.)"},{"name":"applications","description":"Manage applications: the tracking embed (script + collector hashes + collection config) that a site's beacons post to. An application runs on one or more domains (its sites); each beacon's site is resolved at ingest by its page-URL host. Covers application CRUD, script/collector hash rotation, domain (site) membership, and discovery of unregistered hostnames seen hitting the application."},{"name":"releases","description":"Track releases per application so analytics can be correlated with deploys (regressions, rollouts, before/after comparisons)."},{"name":"analytics","description":"**Beta.** Query monitoring data: Core Web Vitals, performance timings, JS errors, third-party impact, sessions, and aggregate experience scores. Supports time-series and breakdown queries with filters. The response shape may still change before general availability."},{"name":"synthetic","description":"**Beta.** Synthetic monitoring (Commerce-Score): scheduled Lighthouse-style lab runs for key pages, with lab-vs-field comparison and historical trends. Requires the organization to opt in to Synthetic Monitoring; available to all organization members. Surface and response shape may still change before general availability."},{"name":"notifications","description":"Rule-based alerting on Core Web Vitals, traffic, and error metrics. Manage rules, inspect send history, run test evaluations, apply presets, and preview rules against historical data."},{"name":"partners","description":"Endpoints for partner organizations that manage multiple client organizations with aggregated billing and usage reporting."},{"name":"collector","description":"Public beacon ingestion endpoint embedded in the browser tracker. Accepts RUM payloads from end-user devices; exempt from the standard response envelope."},{"name":"source","description":"Public delivery of the browser tracking script. ETag-cached and exempt from the standard response envelope."}],"security":[{"bearerAuth":[]}]}