{"openapi":"3.1.0","info":{"title":"Rankscale API","version":"1.0.0","description":"The public Rankscale API.\n\n- **Metrics API** (`/v1/metrics/...`) and **Share Links API** (`/shareLinksAPI/...`): REST on `https://rankscale.ai`, authenticated with an API key. The two APIs use different keys. A key has no scopes: it has the access of the Rankscale user who owns it, including that user's read or write access per brand.\n- **MCP server** (`/mcp` on `https://mcp.rankscale.ai`): OAuth 2.0. It is the only part with named scopes, listed under `mcpOAuth`.\n\nHuman documentation: https://rankscale.ai/api\n\n## Errors\n\nEvery error is JSON. The Metrics API answers `{\"success\": false, \"error\": {\"code\", \"message\"}}` (`ErrorResponse`), and an unknown path under `/v1` or `/api` answers the same shape with a `hint`. The BI endpoints and the Share Links API use the older `{\"error\", \"message\"}` shape (`ShareLinksErrorResponse` for Share Links). Branch on `error.code`, not on the HTTP message.\n\n## Rate limits\n\nThe Metrics API allows 200 requests per minute per API key. `RateLimit-Policy` states that on every response. Authenticated responses add `RateLimit` and the older `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`, and `X-RateLimit-*`. A `429` carries `Retry-After`.\n\n## Versioning and deprecation\n\n- `/v1` is the current and only version. Every response carries `X-API-Version: 1`.\n- Additive changes ship in v1 without notice: new endpoints, new response fields, and new optional request fields or parameters. Clients must ignore response fields they do not know.\n- A breaking change ships as a new version in the path (`/v2`). v1 keeps working next to it.\n- Removing or changing something in v1 is announced at least 6 months before it happens, in the public changelog at https://rankscale.ai/changelog. While the notice runs, the affected responses carry a `Deprecation` header (RFC 9745), a `Sunset` header with the removal date (RFC 8594), and a `Link` header with `rel=\"deprecation\"` that points to the notice.\n- An AI search engine that Rankscale stops supporting stays readable in historical data. Its id is listed with the date it was deprecated and, where there is one, its replacement.\n\n## Metrics API notes\n\nTips:\n- Prefer the Bearer header: `Authorization: Bearer <RANKSCALE_API_KEY>`.\n- Use `https://rankscale.ai` as the base URL and `/v1/metrics/...` paths for requests.\n- Send `X-Request-Id` when you want to correlate a request with support logs; Rankscale echoes it in the response.\n- Watch `X-RateLimit-Remaining` and back off before it reaches zero.\n- Brand Details picker equivalents: `timeFrame` is the date-picker range; `showLastRunMetrics` false is Trailing average and true is Raw latest; `aggregation` is Hourly/Daily/Weekly/Monthly chart buckets, not the trailing-average window.\n- Trailing-average snapshots match Brand Details charts (one window down): `24h`/`7d` → `snapshotH24` (24-hour average; Last 24 hours / Last 7 days), `30d` → `snapshotD7` (7-day average; Last 30 days / This month), `3m`/`1y` → `snapshotD30` (30-day average). Raw latest (`showLastRunMetrics: true`) uses `lastRunMetrics` and ignores that mapping.\n- `/report` uses that mapping via the same Service2 path as the dashboard. `/search-terms-report` uses the same mapping on each term's latest stored snapshot (custom dates infer `timeFrame` first; they do not re-aggregate the range). `/sentiment` scores use the execution window, not a trailing snapshot; `timeFrame` only picks the competitor allowlist (non-shifted: `24h`→H24, `7d`→D7, else D30 — same as the Sentiment tab, not `/report`). `/citations` uses `timeFrame` for `timestampFormat`. `/shopping` and `/ads` use custom dates as the window (`aggregationLevel` rebuckets series).\n- Reporting endpoints accept preset windows (`timeFrame` plus `periodOffset`) or custom ranges (`isoStartDate` plus `isoEndDate`). Custom dates replace the execution window; `timeFrame` is not a no-op (see above). The request custom-range fields are `isoStartDate`/`isoEndDate`; the response echoes the resolved window back as `requestedDateRange.startDate`/`endDate` (read-only, not accepted as inputs).\n- Unknown request fields are ignored and reported in `warnings[]`; valid fields remain active. The default 7d window is used only when no supported window (`timeFrame` or `isoStartDate`/`isoEndDate`) is provided. `/report`, `/citations`, `/search-terms-report`, `/shopping`, and `/ads` return a non-blocking `warnings[]` array naming the ignored field — check it if a call unexpectedly returns only the latest snapshot.\n- Use `__UNTAGGED__` to include untagged search terms and `_orphaned` for search terms without a topic.","termsOfService":"https://rankscale.ai/terms","contact":{"name":"Rankscale support","email":"support@rankscale.ai","url":"https://rankscale.ai"}},"externalDocs":{"description":"Rankscale API documentation","url":"https://rankscale.ai/api"},"servers":[{"url":"https://rankscale.ai","description":"Production hosted API"}],"security":[{"bearerAuth":[]},{"apiKeyQuery":[]}],"tags":[{"name":"Reporting","description":"Dashboard, search-term, sentiment, citation, shopping, ads, sources, fanout, Local Results, and Follow-up Forms reporting. /report and /search-terms-report use the same one-window-down trailing-average snapshots as Brand Details charts; /sentiment, /citations, /shopping, /ads, /sources, /fanout, /local-results, and /follow-up-forms do not."},{"name":"Brands","description":"Workspace brand management endpoints."},{"name":"Search Terms","description":"Workspace search-term management and execution endpoints."},{"name":"Topics","description":"Workspace topic management endpoints."},{"name":"Prompt Research","description":"Prompt research creation and retrieval endpoints."},{"name":"Credits","description":"Credit balance and runway endpoints."},{"name":"Share Links: Brands","description":"List brands and grouped share links available to the API key."},{"name":"Share Links","description":"Create, list, edit, extend, reactivate, and delete public dashboard share links."},{"name":"MCP","description":"The Rankscale MCP server. OAuth 2.0 with named scopes."}],"paths":{"/v1/metrics/report":{"post":{"tags":["Reporting"],"operationId":"createMetricsReport","summary":"Create dashboard metrics report","description":"Returns dashboard-ready brand metrics, competitor metrics, historical data, topic metrics, and engine metrics — same Service2 trailing-average mapping as Brand Details charts. timeFrame selects the display snapshot (one window down: 24h/7d → snapshotH24, 30d → snapshotD7, 3m/1y → snapshotD30). showLastRunMetrics true uses lastRunMetrics (Raw latest). When isoStartDate/isoEndDate are set they select the execution window; still send timeFrame for the snapshot (default 7d). aggregation is chart bucket size only. The API key holder must have read access to the requested brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsReportRequest"},"examples":{"default":{"value":{"brandId":"brand_abc123","timeFrame":"30d","aggregation":"daily","periodOffset":0,"selectedTopic":"all","selectedTags":"all","selectedEngine":["chatgpt_gui","perplexity_gui"],"selectedQuery":"all","includeNotFoundExecutions":true,"showLastRunMetrics":false,"userTimezone":"Europe/Berlin"}},"customRangeTrailingAverage":{"summary":"Custom July window with 7-day trailing average (Brand Details Last 30 days: timeFrame 30d → snapshotD7)","value":{"brandId":"brand_abc123","timeFrame":"30d","aggregation":"daily","isoStartDate":"2026-07-01T00:00:00.000Z","isoEndDate":"2026-07-31T23:59:59.999Z","selectedTopic":"all","selectedTags":"all","showLastRunMetrics":false}}}}}},"responses":{"200":{"description":"Dashboard-ready metrics report.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetricsReportResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/search-terms-report":{"post":{"tags":["Reporting"],"operationId":"createSearchTermsReport","summary":"Create search-term reporting snapshot","description":"Returns latest aggregated metrics per search term, optionally including execution answer texts. Snapshot endpoint using the same one-window-down mapping as Brand Details / /report: without custom dates, 24h/7d → snapshotH24, 30d → snapshotD7, 3m/1y → snapshotD30 (snapshotD7 fallback). Metrics always come from each term's latest stored snapshot — the endpoint does not re-aggregate the requested dates. When isoStartDate/isoEndDate are set, range length infers timeFrame (≤1d → 24h, >1 and ≤7d → 7d, >7 and ≤30d → 30d, >30 and ≤90d → 3m, >90d → 1y) then that frame selects the array; request timeFrame is ignored for metrics. Custom dates and periodOffset only constrain answerTexts. Use /report for historical metrics over an exact range. selectedTopic accepts a topic ID, a case-insensitive topic name, or `_orphaned`; unresolvable values are reported via `warnings[]`. The API key holder must have read access to the requested brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTermsReportRequest"},"examples":{"default":{"value":{"brandId":"brand_abc123","timeFrame":"7d","selectedTopic":"all","selectedTags":"all","selectedEngine":"all","selectedQuery":"all","includeAnswerTexts":true}}}}}},"responses":{"200":{"description":"Search-term reporting snapshot.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTermsReportResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/sentiment":{"post":{"tags":["Reporting"],"operationId":"createSentimentReport","summary":"Create sentiment report","description":"Returns sentiment aggregates and keyword clouds for the own brand and competitors. Scores use the execution window (isoStartDate/isoEndDate or the timeFrame preset), not a trailing-average snapshot. timeFrame still selects the live competitor-allowlist snapshot family (non-shifted: 24h→H24, 7d→D7, else D30) — the same helper as the dashboard Sentiment tab, not /report's one-window-down display mapping. Default 7d. The API key holder must have read access to the requested brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SentimentRequest"},"examples":{"default":{"value":{"brandId":"brand_abc123","timeFrame":"30d","selectedEngine":"perplexity_gui"}}}}}},"responses":{"200":{"description":"Sentiment report.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SentimentResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/shopping":{"post":{"tags":["Reporting"],"operationId":"createShoppingReport","summary":"Create shopping report","description":"Returns shopping aggregates for products, merchants, buybox winners, detection-rate series, and engine breakdowns. Shopping data comes from GUI shopping-capable engines (chatgpt_gui, google_ai_mode_gui, bing_copilot_gui). The API pages search terms internally and merges pages server-side. Defaults to top 200 items and 100 providers; pass uncapped=true to disable caps. The API key holder must have read access to the requested brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShoppingRequest"},"examples":{"default":{"value":{"brandId":"brand_abc123","timeFrame":"30d","selectedEngine":["chatgpt_gui","google_ai_mode_gui"]}}}}}},"responses":{"200":{"description":"Shopping report.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShoppingResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/ads":{"post":{"tags":["Reporting"],"operationId":"createAdsReport","summary":"Create ads report","description":"Returns sponsored-ad placement aggregates: advertisers, appearance rates, share of voice, creative samples, and ads-by-day series. Ad placements come from ad-eligible GUI engines only (chatgpt_gui, google_ai_mode_gui). The API pages search terms internally and merges pages server-side. Defaults to top 100 advertisers; pass uncapped=true to disable the cap. The API key holder must have read access to the requested brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdsRequest"},"examples":{"default":{"value":{"brandId":"brand_abc123","timeFrame":"30d"}}}}}},"responses":{"200":{"description":"Ads report.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/sources":{"post":{"tags":["Reporting"],"operationId":"createSourcesReport","summary":"Create sources report","description":"Returns Source Box domain aggregates: cross-term domain leaderboard, per-search-term engine groups, and own-domain overview. The API pages search terms internally and merges pages server-side. Defaults to top 100 domains and 200 terms; pass uncapped=true to disable the caps.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourcesRequest"},"examples":{"default":{"value":{"brandId":"brand_abc123","timeFrame":"30d"}}}}}},"responses":{"200":{"description":"Sources report.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SourcesResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/fanout":{"post":{"tags":["Reporting"],"operationId":"createFanoutReport","summary":"Create query fanout report","description":"Returns Query Fanout aggregates matching Brand Details Insights: coverage KPIs, top fanout queries, daily activity, probed site domains, and appendix signals. Pages and finalizes server-side with the same shared merge helpers as the app. Defaults to top 200 queries and 50 site domains; pass uncapped=true to disable the caps.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FanoutRequest"},"examples":{"default":{"value":{"brandId":"brand_abc123","timeFrame":"30d"}}}}}},"responses":{"200":{"description":"Fanout report.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FanoutResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/local-results":{"post":{"tags":["Reporting"],"operationId":"createLocalResultsReport","summary":"Create Local Results report","description":"Returns the Local Results report for a brand: how often AI engines show Google local and Maps place results for tracked prompts and whether the brand's places appear. Includes Share, Avg. Position, Detection % and Top 3 rate with previous-period values, a per-engine breakdown, top places by Share, a trend for the brand and up to 5 places, prompt coverage per engine and insights. Numbers match Brand Details > Local Results. Only map-capable engines count. Pages and finalizes server-side with the same shared helpers as the app. Defaults to the top 50 places and 100 prompt rows; pass uncapped=true to disable the caps. Requests that need more than 200 prompt pages (10,000 prompts) are rejected with 400, narrow the filters and retry.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocalResultsRequest"},"examples":{"default":{"value":{"brandId":"brand_abc123","timeFrame":"30d"}},"customRange":{"value":{"brandId":"brand_abc123","isoStartDate":"2026-09-01","isoEndDate":"2026-09-30","selectedEngine":["chatgpt_gui","google_ai_mode_gui"],"placeLimit":20}}}}}},"responses":{"200":{"description":"Local Results report.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocalResultsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/follow-up-forms":{"post":{"tags":["Reporting"],"operationId":"createFollowUpFormsReport","summary":"Create follow-up forms report","description":"Returns the ChatGPT Follow-up Forms report matching Brand Details Insights: run counts and form rate with the previous period, a form-rate series, top clarifying questions with shown and pre-selected answer shares, follow-up prompt templates and per-prompt form rates. Covers ChatGPT only (engine chatgpt_gui), so there is no engine filter. Windows are UTC calendar days with an inclusive end day; presets default to 7d. Form rate = runs with a form / checked runs; unchecked runs (before tracking started on trackingStartedAt, or without stored data) are excluded, and days before tracking started appear in series with formRate null. The previous period has the same length as the current window and is skipped (previousStatus before_rollout) when it ends before tracking started. Defaults to top 50 questions, 25 follow-up prompts and 100 prompts; pass uncapped=true to disable the caps. Returns 400 when more than 10,000 prompts match (narrow topic, tags, query or date range) or when the response stays above the size ceiling after trimming.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowUpFormsRequest"},"examples":{"default":{"value":{"brandId":"brand_abc123","timeFrame":"30d"}},"customRange":{"value":{"brandId":"brand_abc123","isoStartDate":"2026-10-10","isoEndDate":"2026-10-31","aggregationLevel":"daily","questionLimit":20}}}}}},"responses":{"200":{"description":"Follow-up forms report.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FollowUpFormsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/executions":{"post":{"tags":["Reporting"],"operationId":"listExecutions","summary":"List raw search-term executions","description":"Returns raw searchTermExecutions records as structured JSON for a list of search term IDs. Newest first, cursor-paginated. Optional isoStartDate/isoEndDate filter the execution window. Internal cost fields (usage) and htmlSnapshotPath are never returned; rawProviderResponse is omitted unless includeRawProviderResponse is true. Every requested search term must belong to the workspace and pass brand read access; otherwise the request fails with no partial data.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecutionsRequest"},"examples":{"default":{"value":{"searchTermIds":["st_abc123","st_def456"],"isoStartDate":"2026-01-01","isoEndDate":"2026-01-31","limit":100}}}}}},"responses":{"200":{"description":"Execution page.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecutionsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/citations":{"post":{"tags":["Reporting"],"operationId":"createCitationsReport","summary":"Create citations report","description":"Returns citation analytics, including URL/domain aggregations and citation breakdowns by engine, query, own brand, and competitors. isoStartDate/isoEndDate select the citation window; timeFrame still selects per-URL timestampFormat (24h=full, 7d/30d=daily, 3m/1y=weekly; default 7d). The API key holder must have read access to the requested brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"name":"deduplicated","in":"query","required":false,"description":"Deduplicates citation response paths where supported.","schema":{"type":"boolean"}},{"name":"uncapped","in":"query","required":false,"description":"Bypasses the default 5,000 unique-URL detail cap for API callers. A final response-size guard may still trim oversized JSON responses.","schema":{"type":"boolean"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CitationsRequest"},"examples":{"default":{"value":{"brandId":"brand_abc123","timeFrame":"30d","selectedTopic":"all","selectedEngine":"all","selectedQuery":"all"}}}}}},"responses":{"200":{"description":"Citations report.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CitationsResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/brands":{"get":{"tags":["Brands"],"operationId":"listBrands","summary":"List brands","description":"Lists brands for the authenticated workspace that the API key holder can read. Soft-deleted brands are omitted, matching the dashboard. Pagination and `limit` apply to live brands only.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/LimitQuery"}],"responses":{"200":{"description":"Workspace brands.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandListResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Brands"],"operationId":"createBrand","summary":"Create brand","description":"Creates a brand in the effective workspace. For workspace-member API keys in managed workspaces, this requires workspace-level write access (same gate as UI users). Workspace owners and whitelabel workspace members are exempt from that managed-workspace check. Plan brand limits are enforced.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandCreateRequest"}}}},"responses":{"201":{"description":"Brand created.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/brands/{brandId}":{"patch":{"tags":["Brands"],"operationId":"patchBrand","summary":"Patch brand","description":"Partially updates public brand fields. Internal identifiers and ownership fields cannot be overwritten. For API keys created by workspace members, brand write permission is required. Soft-deleted brands return the same 404 as a missing brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/BrandIdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandPatchRequest"}}}},"responses":{"200":{"description":"Brand updated.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Brands"],"operationId":"deleteBrand","summary":"Delete brand","description":"Deletes a brand owned by the workspace and detaches or deactivates related records. For API keys created by workspace members, brand write permission is required.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/BrandIdPath"}],"responses":{"200":{"description":"Brand deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/brands/{brandId}/analysis":{"get":{"tags":["Brands"],"operationId":"getBrandFalsePositiveAnalysis","summary":"Run and retrieve false-positive/false-negative analysis","description":"Runs false-positive and false-negative analysis for the brand using the currently saved brand names (`name` + `brandInfo[0].brands`). Requires brand read access.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/BrandIdPath"}],"responses":{"200":{"description":"Analysis results.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandAnalysisResultsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Brands"],"operationId":"runBrandFalsePositiveAnalysis","summary":"Run false-positive/false-negative analysis with optional names override","description":"Runs false-positive and false-negative analysis for the brand. When `ownBrandNames` is provided, those names are used for matching during this run; otherwise the saved brand names are used. Requires brand read access.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/BrandIdPath"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandAnalysisRunRequest"}}}},"responses":{"200":{"description":"Analysis results.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandAnalysisResultsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/brands/{brandId}/analysis/recalculate":{"post":{"tags":["Brands"],"operationId":"recalculateBrandFalsePositiveAnalysis","summary":"Trigger brand metrics recalculation after analysis cleanup","description":"Triggers metrics recalculation for a brand, matching the Brand Settings Services action. Send `searchTermIds` to recalculate those terms, or `allSearchTerms: true` to recalculate every search term on the brand. The two forms are mutually exclusive; sending both or neither returns `422`. Each id is trimmed, and any id that is empty after trimming fails the request with `422`. Requires brand write access.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/BrandIdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandAnalysisRecalculateRequest"}}}},"responses":{"200":{"description":"Recalculation accepted and completed.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandAnalysisRecalculateResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/brands/{brandId}/analysis/brand-names":{"post":{"tags":["Brands"],"operationId":"addBrandAnalysisBrandName","summary":"Add brand name for analysis matching","description":"Adds a brand name (or wildcard pattern) to the analysis matching list used by false-positive/false-negative analysis. Updates brands and products on the first brandInfo entry and leaves other fields on that entry, including ISO-country and ISO-language, plus later brandInfo entries. Requires brand write access.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/BrandIdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandAnalysisBrandNameRequest"}}}},"responses":{"200":{"description":"Brand name added or already present.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandAnalysisBrandNamesResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Brands"],"operationId":"removeBrandAnalysisBrandName","summary":"Remove brand name for analysis matching","description":"Removes a brand name (or wildcard pattern) from `brandInfo` used for analysis matching. Updates brands and products on the first brandInfo entry and leaves other fields on that entry, including ISO-country and ISO-language, plus later brandInfo entries. Deleting the default `Name*` wildcard persists and is not re-seeded. The brand document `name` stays in default analysis matching. Requires brand write access.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/BrandIdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandAnalysisBrandNameRequest"}}}},"responses":{"200":{"description":"Brand name removed or already absent.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandAnalysisBrandNamesResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/brands/{brandId}/analysis/labels":{"post":{"tags":["Brands"],"operationId":"applyBrandAnalysisLabels","summary":"Mark or unmark Your Brand on analysis findings","description":"Rewrites stored Your Brand labels on the executions and citations for current analysis findings. `mark_own_brand` applies to false negatives (`negatives`): one `brandName`, or `all: true` for every current false negative. `unmark_own_brand` applies to false positives (`results`): one `brandName`, or `all: true` for every current false positive. The server re-runs analysis with the saved brand names and writes only those matches. A `brandName` that is not a current finding returns `applied: false` and writes nothing. Requires brand write access. Recalculate after label changes so metrics pick them up.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/BrandIdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandAnalysisLabelsRequest"}}}},"responses":{"200":{"description":"Labels applied, or no current finding matched the requested name.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BrandAnalysisLabelsResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/search-terms":{"get":{"tags":["Search Terms"],"operationId":"listSearchTerms","summary":"List search terms for a brand","description":"Lists operational search terms for a brand. The brand must belong to the effective workspace and the API key holder must have read access to that brand. Defaults to at most 1000 terms (limit max 5000); pass uncapped=true to return every operational search term.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"name":"brandId","in":"query","required":true,"description":"Workspace brand ID.","schema":{"type":"string"}},{"$ref":"#/components/parameters/LimitQuery"},{"name":"uncapped","in":"query","required":false,"description":"When true, return all operational search terms and ignore limit.","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Search terms for the brand.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTermListResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Search Terms"],"operationId":"createSearchTerm","summary":"Create search term(s)","description":"Creates one search term (single-object body) or 1–100 terms (body.searchTerms array). Validation is all-or-nothing: any invalid engine/region/brand/topic rejects the whole request before any write. Each create input expands into one created search-term document per valid engine in aiSearchEngines (omit or send [] to use the default engine). The expanded create count must stay within 1–100 writes. Unknown engines return invalid_engine (lists all valid IDs). Deprecated engines return deprecated_engine. Unknown or engine-unsupported regions return invalid_region.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/SearchTermCreateRequest"},{"$ref":"#/components/schemas/SearchTermBatchCreateRequest"}]}}}},"responses":{"201":{"description":"Search term created.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/IdResponse"},{"$ref":"#/components/schemas/SearchTermBatchCreateResponse"}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"patch":{"tags":["Search Terms"],"operationId":"patchSearchTermsBatch","summary":"Batch patch search terms","description":"Patches 1–100 search terms in one request. Validation is all-or-nothing before write; prefer this over N sequential PATCH /{searchTermId} calls. Engine and region validation matches create: invalid_engine, deprecated_engine, invalid_region.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTermBatchPatchRequest"}}}},"responses":{"200":{"description":"Search terms updated.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTermBatchPatchResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/search-terms/{searchTermId}":{"patch":{"tags":["Search Terms"],"operationId":"patchSearchTerm","summary":"Patch search term","description":"Partially updates public search-term fields. Caller-provided myBrand is ignored. brandRef and competitors cannot be changed after creation; including either field returns 400 validation_error. For API keys created by workspace members, brand write permission is required for the search term's associated brand. If scheduling fields change, the next scheduled execution time is recalculated. Patches that would activate or keep an active search term on a deprecated engine are blocked with deprecated_engine.\n\nWhen patching aiSearchEngines, pass a single-element array with a known engine ID. More than one engine or an empty array is rejected with 400 validation_error. Unknown engines return 400 invalid_engine and deprecated engines return 400 deprecated_engine. Search terms that already store several engines can still be patched on other fields. Switching engines does not create additional search terms.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/SearchTermIdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTermPatchRequest"}}}},"responses":{"200":{"description":"Search term updated.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Search Terms"],"operationId":"deleteSearchTerm","summary":"Delete search term","description":"Deletes a search term, citation chunks, and related brand/topic references. For API keys created by workspace members, brand write permission is required for the search term's associated brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/SearchTermIdPath"}],"responses":{"200":{"description":"Search term deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/search-terms/{searchTermId}/activate":{"post":{"tags":["Search Terms"],"operationId":"activateSearchTerm","summary":"Activate search term","description":"Activates a search term and schedules the next run when applicable. For API keys created by workspace members, brand write permission is required for the search term's associated brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/SearchTermIdPath"}],"responses":{"200":{"description":"Search term activated.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/search-terms/{searchTermId}/deactivate":{"post":{"tags":["Search Terms"],"operationId":"deactivateSearchTerm","summary":"Deactivate search term","description":"Deactivates a search term and clears the next scheduled execution time. For API keys created by workspace members, brand write permission is required for the search term's associated brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/SearchTermIdPath"}],"responses":{"200":{"description":"Search term deactivated.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/search-terms/{searchTermId}/run":{"post":{"tags":["Search Terms"],"operationId":"runSearchTerm","summary":"Run search term immediately","description":"Runs one search term through the shared backend execution pipeline. For API keys created by workspace members, this checks brand write permission for the search term's associated brand. Unauthorized term-level access is reported in the success envelope (data.success=false and term result errors), not as a top-level 403 response.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/SearchTermIdPath"},{"name":"X-Rankscale-Async","in":"header","required":false,"description":"When set to `1` and the server-side manual queue gate enables `metrics_api` for the workspace, the call accepts the run and returns `{ run_id, status }` with HTTP 202. Omitted or any other value keeps the current blocking v1 envelope. The gate is default-off.","schema":{"type":"string","enum":["1"]}},{"name":"Idempotency-Key","in":"header","required":false,"description":"Optional idempotency key for the async path only. Distinct from X-Request-Id. Same key plus same term replays the same run_id; same key plus a different term returns 409. When X-Rankscale-Async is 1 but async is not available for the request, the key still means one run: an async run it already stored is returned with 202; a new key runs synchronously once and its answer is stored; a later request with that key gets the stored answer again (same status and body, header Idempotent-Replayed: true) and nothing runs or is charged again. While that run is in progress the key answers 409 idempotency_key_in_progress; if its answer was lost it answers 409 idempotency_key_outcome_unknown and never runs again. If the key cannot be checked, the call returns 503 submission_unresolved. Ignored without X-Rankscale-Async: 1.","schema":{"type":"string"}},{"name":"X-Rankscale-Run-Id","in":"header","required":false,"description":"Async path only, for a request WITHOUT Idempotency-Key. Send error.details.run_id from a submission_unresolved 503 to finish that same submission: the server returns the run if it exists, or stores it under exactly this id, so the retry can never create a second run. 20 letters or digits. With an Idempotency-Key, without X-Rankscale-Async, or malformed, it is a 400. If async is not available for the request, the call answers 503 and never runs synchronously.","schema":{"type":"string","pattern":"^[A-Za-z0-9]{20}$"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false}}}},"responses":{"200":{"description":"Execution summary. The envelope is successful even when the term-level result failed; inspect data.success and data.results.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTermRunResponse"}}}},"202":{"description":"Async acceptance when X-Rankscale-Async is 1 and the manual queue gate is enabled for metrics_api. Acceptance is not execution success.","content":{"application/json":{"schema":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean"},"data":{"type":"object","required":["run_id","status"],"properties":{"run_id":{"type":"string"},"status":{"type":"string","enum":["queued","running","partial","completed","failed","unknown"]}}}}}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"409":{"description":"error.code `conflict`: the Idempotency-Key or X-Rankscale-Run-Id was already used for a different request (another term, workspace or actor). Nothing is dispatched and no existing run is disclosed. With X-Rankscale-Async: 1 and an Idempotency-Key whose run fell back to the synchronous runner: `idempotency_key_in_progress` (that run is still going; retry the same key after Retry-After) or `idempotency_key_outcome_unknown` (that run started and its answer was lost; it never runs again under this key). Nothing runs.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"description":"Async path only; error.code tells the two cases apart. `unavailable`: the run was not queued and will not run; nothing is charged and no run_id is returned. Retry with a new Idempotency-Key (or none); replaying the same key returns that run with status failed. `submission_unresolved`: the server could not confirm whether the run was stored. It is not a rejection: the run may exist and may still execute. After Retry-After seconds, retry the SAME request with the same identity: the same Idempotency-Key if you sent one, otherwise X-Rankscale-Run-Id set to error.details.run_id. Never mint a new key for it. The retry returns 202 with that run, or the same 503 while storage is still unavailable. A 404 from GET /v1/metrics/search-term-runs/{run_id} is not final until a retry confirms. The blocking v1 path is never used as a fallback.","headers":{"Retry-After":{"description":"Seconds to wait before retrying a submission_unresolved answer.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["success","error"],"properties":{"success":{"type":"boolean","enum":[false]},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","enum":["unavailable","submission_unresolved"]},"message":{"type":"string"},"details":{"type":"object","description":"submission_unresolved only.","properties":{"run_id":{"type":"string","description":"Keyless requests only: resume with X-Rankscale-Run-Id set to this value."},"retry_with_header":{"type":"string","enum":["X-Rankscale-Run-Id","Idempotency-Key"]}}}}}}}}}}}}},"/v1/metrics/topics":{"get":{"tags":["Topics"],"operationId":"listTopics","summary":"List topics for a brand","description":"Lists topics attached to a brand. The brand must belong to the effective workspace and the API key holder must have read access to that brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"name":"brandRef","in":"query","required":true,"description":"Brand ID whose topics should be listed. Note: management endpoints name this parameter `brandRef`, while reporting POST bodies call the same value `brandId`; sending `brandId` here fails with 422.","schema":{"type":"string"}},{"$ref":"#/components/parameters/LimitQuery"}],"responses":{"200":{"description":"Topics attached to the brand.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopicListResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Topics"],"operationId":"createTopic","summary":"Create topic","description":"Creates a topic attached to a brand, resolves the stored string myBrand value from brandRef, and updates the brand operational topics list. For API keys created by workspace members, brand write permission is required for the referenced brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopicCreateRequest"}}}},"responses":{"201":{"description":"Topic created.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/topics/{topicId}":{"patch":{"tags":["Topics"],"operationId":"patchTopic","summary":"Patch topic","description":"Updates topic metadata or moves the topic to another brand. For API keys created by workspace members, brand write permission is required for the topic's current brand and, when moving it, the destination brand. Detaching a topic from its brand is forbidden. Brand operational topics are kept in sync, and the stored string myBrand is refreshed from brandRef when the brand association changes.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/TopicIdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopicPatchRequest"}}}},"responses":{"200":{"description":"Topic updated.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IdResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"delete":{"tags":["Topics"],"operationId":"deleteTopic","summary":"Delete topic","description":"Deletes a topic, unassigns linked search terms, and removes the topic from the associated brand operational topics list. For API keys created by workspace members, brand write permission is required for the topic brand and each linked search term brand before cascaded updates are applied.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/TopicIdPath"}],"responses":{"200":{"description":"Topic deleted.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeletedResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/credits":{"get":{"tags":["Credits"],"operationId":"getCredits","summary":"Get credits","description":"Returns current credit balances and credits in flight. Runway simulation and dashboard burn-rate metrics are calculated and returned only when `includeRunway=true`.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/IncludeRunwayQuery"}],"responses":{"200":{"description":"Credit balances. Includes runway fields only when includeRunway=true.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreditsResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"404":{"$ref":"#/components/responses/NotFound"},"405":{"$ref":"#/components/responses/MethodNotAllowed"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/prompt-researches":{"get":{"tags":["Prompt Research"],"operationId":"listPromptResearches","summary":"List prompt researches","description":"Lists prompt research documents for the authenticated workspace owner context. Optional brandId narrows the list to one accessible brand.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/LimitQuery"},{"name":"brandId","in":"query","required":false,"description":"Optional brand filter. Must be readable by the API key holder.","schema":{"type":"string"}}],"responses":{"200":{"description":"Prompt research list.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromptResearchListResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}},"post":{"tags":["Prompt Research"],"operationId":"createPromptResearch","summary":"Create prompt research","description":"Creates a running prompt research record, enqueues background execution, and returns the running record so clients can poll via list/get endpoints.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromptResearchCreateRequest"}}}},"responses":{"202":{"description":"Prompt research accepted and queued for background execution.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromptResearchCreateResponse"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"422":{"$ref":"#/components/responses/ValidationError"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/v1/metrics/prompt-researches/{promptResearchId}":{"get":{"tags":["Prompt Research"],"operationId":"getPromptResearch","summary":"Get prompt research","description":"Fetches one prompt research document by ID if it belongs to the authenticated workspace context.","parameters":[{"$ref":"#/components/parameters/RequestIdHeader"},{"$ref":"#/components/parameters/PromptResearchIdPath"}],"responses":{"200":{"description":"Prompt research document.","headers":{"X-Request-Id":{"$ref":"#/components/headers/RequestId"},"X-API-Version":{"$ref":"#/components/headers/ApiVersion"},"X-RateLimit-Limit":{"$ref":"#/components/headers/RateLimitLimit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/RateLimitRemaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/RateLimitReset"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"},"Sunset":{"$ref":"#/components/headers/Sunset"},"Deprecation":{"$ref":"#/components/headers/Deprecation"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PromptResearchGetResponse"}}}},"401":{"$ref":"#/components/responses/AuthFailed"},"403":{"$ref":"#/components/responses/Forbidden"},"404":{"$ref":"#/components/responses/NotFound"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"}}}},"/shareLinksAPI/brands":{"get":{"tags":["Share Links: Brands"],"operationId":"listShareLinkBrands","summary":"List brands and grouped links","description":"Returns all brands owned by the effective workspace, with active and inactive share links grouped under each brand.","responses":{"200":{"description":"Brands with active and inactive share links.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListBrandsResponse"},"examples":{"default":{"value":{"brands":[{"id":"brand_abc123","name":"Acme Inc","createdAt":"2026-01-15T12:34:56.789Z","activeLinks":[{"id":"share_abc123","token":"token_abc123","brandId":"brand_abc123","createdAt":"2026-02-01T10:00:00.000Z","expiresAt":null,"disabled":false,"allowedTabs":["Dashboard","Competitors"],"initialFilters":{"timeFrame":"7d","selectedAggregation":"daily"},"lockFilters":true,"views":0,"whitelabel":false,"url":"https://rankscale.ai/dashboard/share/brand_abc123?token=token_abc123"}],"inactiveLinks":[]}]}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/Internal"}},"security":[{"shareLinksBearerAuth":[]},{"shareLinksApiKeyQuery":[]}]}},"/shareLinksAPI/share-links":{"get":{"tags":["Share Links"],"operationId":"listShareLinks","summary":"List share links","description":"Returns share links for the effective workspace. Use `brandId` to filter to one brand and `active=true` to return only links that are not disabled and not expired.","parameters":[{"$ref":"#/components/parameters/BrandIdQuery"},{"$ref":"#/components/parameters/ActiveQuery"}],"responses":{"200":{"description":"Share links matching the filters.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ListShareLinksResponse"},"examples":{"default":{"value":{"links":[{"id":"share_abc123","token":"token_abc123","brandId":"brand_abc123","createdAt":"2026-02-01T10:00:00.000Z","expiresAt":null,"disabled":false,"allowedTabs":["Dashboard","Competitors","Citations"],"initialFilters":{"timeFrame":"30d","selectedAggregation":"daily","selectedEngine":"ChatGPT"},"lockFilters":true,"views":12,"whitelabel":false,"url":"https://rankscale.ai/dashboard/share/brand_abc123?token=token_abc123"}]}}}}}},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/PermissionDenied"},"404":{"$ref":"#/components/responses/ShareLinksNotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/Internal"}},"security":[{"shareLinksBearerAuth":[]},{"shareLinksApiKeyQuery":[]}]},"post":{"tags":["Share Links"],"operationId":"createShareLink","summary":"Create share link","description":"Creates a public, read-only dashboard share link for a brand. Supports no-expiry links with `noExpiry: true`.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateShareLinkRequest"},"examples":{"noExpiry":{"summary":"No-expiry locked dashboard","value":{"brandId":"brand_abc123","allowedTabs":["Dashboard","Competitors","Citations"],"initialFilters":{"timeFrame":"30d","selectedAggregation":"daily","selectedTopic":"all","selectedEngine":"ChatGPT","selectedQuery":"pricing","selectedFilters":{"topics":["Onboarding","Support"],"engines":["ChatGPT","Perplexity"],"queries":"all"},"includeNotFoundExecutions":true,"showLastRunMetrics":false,"periodOffset":0},"lockFilters":true,"noExpiry":true,"whitelabel":false}}}}}},"responses":{"201":{"description":"Created share link.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLink"}}}},"400":{"$ref":"#/components/responses/InvalidArgument"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/PermissionDenied"},"404":{"$ref":"#/components/responses/ShareLinksNotFound"},"412":{"$ref":"#/components/responses/FailedPrecondition"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/Internal"}},"security":[{"shareLinksBearerAuth":[]},{"shareLinksApiKeyQuery":[]}]}},"/shareLinksAPI/share-links/{shareId}":{"patch":{"tags":["Share Links"],"operationId":"updateShareLink","summary":"Edit share link","description":"Updates mutable share link settings. Send any subset of fields.","parameters":[{"$ref":"#/components/parameters/ShareIdPath"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdateShareLinkRequest"},"examples":{"setExplicitExpiry":{"summary":"Set explicit expiry","value":{"expiresAt":"2026-12-31T23:59:59.000Z"}},"disable":{"summary":"Disable link","value":{"disabled":true}}}}}},"responses":{"200":{"description":"Updated share link.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLink"}}}},"400":{"$ref":"#/components/responses/InvalidArgument"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/PermissionDenied"},"404":{"$ref":"#/components/responses/ShareLinksNotFound"},"412":{"$ref":"#/components/responses/FailedPrecondition"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/Internal"}},"security":[{"shareLinksBearerAuth":[]},{"shareLinksApiKeyQuery":[]}]},"delete":{"tags":["Share Links"],"operationId":"deleteShareLink","summary":"Delete share link","description":"Deletes a share link and removes the public token mapping.","parameters":[{"$ref":"#/components/parameters/ShareIdPath"}],"responses":{"200":{"description":"Share link deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeleteShareLinkResponse"},"examples":{"default":{"value":{"success":true}}}}}},"400":{"$ref":"#/components/responses/InvalidArgument"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/PermissionDenied"},"404":{"$ref":"#/components/responses/ShareLinksNotFound"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/Internal"}},"security":[{"shareLinksBearerAuth":[]},{"shareLinksApiKeyQuery":[]}]}},"/shareLinksAPI/share-links/{shareId}/extend":{"post":{"tags":["Share Links"],"operationId":"extendShareLink","summary":"Extend or reactivate share link","description":"Adds 30 days to an eligible link. Send `reactivate: true` to re-enable an inactive or expired link while respecting active-link limits.","parameters":[{"$ref":"#/components/parameters/ShareIdPath"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtendShareLinkRequest"},"examples":{"reactivate":{"value":{"reactivate":true}},"extend":{"value":{"reactivate":false}}}}}},"responses":{"200":{"description":"Extended or reactivated share link.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExtendShareLinkResponse"},"examples":{"default":{"value":{"id":"share_abc123","expiresAt":"2026-03-02T10:00:00.000Z","disabled":false,"url":"https://rankscale.ai/dashboard/share/brand_abc123?token=token_abc123"}}}}}},"400":{"$ref":"#/components/responses/InvalidArgument"},"401":{"$ref":"#/components/responses/Unauthenticated"},"403":{"$ref":"#/components/responses/PermissionDenied"},"404":{"$ref":"#/components/responses/ShareLinksNotFound"},"412":{"$ref":"#/components/responses/FailedPrecondition"},"429":{"$ref":"#/components/responses/TooManyRequests"},"500":{"$ref":"#/components/responses/Internal"}},"security":[{"shareLinksBearerAuth":[]},{"shareLinksApiKeyQuery":[]}]}},"/mcp":{"servers":[{"url":"https://mcp.rankscale.ai","description":"Rankscale MCP server"}],"post":{"tags":["MCP"],"operationId":"mcpStreamableHttp","summary":"Call the Rankscale MCP server","description":"Streamable HTTP endpoint of the Rankscale MCP server. Send a JSON-RPC 2.0 message with `Accept: application/json, text/event-stream`. The reply is JSON or a server-sent event stream.\n\nEvery call needs `mcp:read`. Tools that create or change search terms, topics, or dashboard views also need `mcp:write:content`. Tools that spend credits need `mcp:execute`.\n\nTool list and permissions: https://rankscale.ai/docs/mcp","security":[{"mcpOAuth":["mcp:read"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"A JSON-RPC 2.0 request or notification.","required":["jsonrpc","method"],"properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"type":["string","integer"],"description":"Omitted for notifications."},"method":{"type":"string","examples":["tools/list"]},"params":{"type":"object"}}}}}},"responses":{"200":{"description":"The JSON-RPC response, as JSON or as a text/event-stream.","content":{"application/json":{"schema":{"type":"object"}},"text/event-stream":{"schema":{"type":"string"}}}},"401":{"description":"The bearer token is missing or invalid. `WWW-Authenticate` carries `resource_metadata`, the URL of the RFC 9728 protected resource metadata. The body is the OAuth bearer error (RFC 6750) as JSON.","headers":{"WWW-Authenticate":{"description":"Bearer challenge with the `resource_metadata` URL.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/OAuthBearerError"},"example":{"error":"invalid_token","error_description":"Missing Authorization header"}}}},"default":{"description":"Any other failure. A protocol error is a JSON-RPC 2.0 error object. Tool failures are reported inside a normal 200 result.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JsonRpcErrorResponse"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Preferred API key authentication. Send `Authorization: Bearer <RANKSCALE_API_KEY>`."},"apiKeyQuery":{"type":"apiKey","in":"query","name":"api_key","description":"Alternative API key authentication for clients that cannot set headers."},"shareLinksBearerAuth":{"type":"http","scheme":"bearer","description":"Share Links API key sent as `Authorization: Bearer <API_KEY>`."},"shareLinksApiKeyQuery":{"type":"apiKey","in":"query","name":"api_key","description":"Share Links API key sent as a query parameter when headers are unavailable."},"mcpOAuth":{"type":"oauth2","description":"OAuth 2.0 authorization code flow with PKCE (S256). Clients register themselves with dynamic client registration. The user picks the permissions when connecting, so a token carries only the scopes that were granted.","flows":{"authorizationCode":{"authorizationUrl":"https://oauthhttp-yknc56emjq-uc.a.run.app/oauth/authorize","tokenUrl":"https://oauthhttp-yknc56emjq-uc.a.run.app/oauth/token","refreshUrl":"https://oauthhttp-yknc56emjq-uc.a.run.app/oauth/token","scopes":{"mcp:read":"Read your Rankscale data","mcp:write:content":"Create and update your search terms, topics, and dashboards","mcp:execute":"Run search terms and activate tracking"}}},"x-oauth-authorization-server-metadata":"https://mcp.rankscale.ai/.well-known/oauth-authorization-server","x-oauth-protected-resource-metadata":"https://mcp.rankscale.ai/.well-known/oauth-protected-resource"}},"headers":{"CacheControl":{"description":"Error and workspace-management responses send `private, no-store` so Firebase Hosting does not CDN-cache them.","schema":{"type":"string","example":"private, no-store"}},"RequestId":{"description":"Correlation ID generated by Rankscale or echoed from the request.","schema":{"type":"string"}},"ApiVersion":{"description":"Hosted Metrics API version.","schema":{"type":"string","example":"1"}},"RateLimitLimit":{"description":"Requests allowed per minute for the API key.","schema":{"type":"integer","example":200}},"RateLimitRemaining":{"description":"Remaining requests in the current window.","schema":{"type":"integer","example":199}},"RateLimitReset":{"description":"Seconds until the current rate-limit window resets.","schema":{"type":"integer","example":42}},"RateLimitPolicy":{"description":"The rate-limit policy: a named quota and its window in seconds. `\"default\";q=200;w=60` is 200 requests per 60 seconds per API key. Sent on every Metrics API response, with or without a key.","schema":{"type":"string","example":"\"default\";q=200;w=60"}},"RateLimit":{"description":"Remaining quota and seconds until the window resets, for the key that made the request: `\"default\";r=150;t=42`. Sent on authenticated responses.","schema":{"type":"string","example":"\"default\";r=150;t=42"}},"RetryAfter":{"description":"Seconds to wait before the next request. Sent on a 429.","schema":{"type":"integer","example":17}},"Sunset":{"description":"HTTP date after which the endpoint or field is removed (RFC 8594). Only present during a deprecation notice period.","schema":{"type":"string","example":"Tue, 30 Jun 2027 00:00:00 GMT"}},"Deprecation":{"description":"Present while the endpoint or field is deprecated (RFC 9745), as a structured-field date such as `@1767225600`. A `Link` header with `rel=\"deprecation\"` points to the notice.","schema":{"type":"string","example":"@1767225600"}}},"parameters":{"RequestIdHeader":{"name":"X-Request-Id","in":"header","required":false,"description":"Optional client-provided correlation ID. The API echoes it when supplied.","schema":{"type":"string"}},"LimitQuery":{"name":"limit","in":"query","required":false,"description":"Maximum number of records to return.","schema":{"type":"integer","minimum":1,"maximum":5000,"default":1000}},"IncludeRunwayQuery":{"name":"includeRunway","in":"query","required":false,"description":"When true, calculates and returns runway simulation plus dashboard burn-rate metrics. Default false returns balances only. Omit the parameter for the default. Empty, repeated, or other values return 422.","schema":{"type":"boolean","default":false}},"BrandIdPath":{"name":"brandId","in":"path","required":true,"description":"Brand ID.","schema":{"type":"string"}},"SearchTermIdPath":{"name":"searchTermId","in":"path","required":true,"description":"Search term ID.","schema":{"type":"string"}},"TopicIdPath":{"name":"topicId","in":"path","required":true,"description":"Topic ID.","schema":{"type":"string"}},"PromptResearchIdPath":{"name":"promptResearchId","in":"path","required":true,"description":"Prompt research document ID.","schema":{"type":"string"}},"BrandIdQuery":{"name":"brandId","in":"query","required":false,"schema":{"type":"string"},"description":"Optional brand ID filter. The brand must belong to the effective workspace."},"ActiveQuery":{"name":"active","in":"query","required":false,"schema":{"type":"boolean"},"description":"When true, returns only links that are not disabled and either have no expiry or expire in the future."},"ShareIdPath":{"name":"shareId","in":"path","required":true,"schema":{"type":"string"},"description":"Share link ID returned by list or create calls."}},"responses":{"AuthFailed":{"description":"Missing or invalid API key.","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"auth_failed","message":"Authentication failed"}}}}},"BadRequest":{"description":"Invalid business input or request state, including an incomplete or invalid isoStartDate/isoEndDate pair.","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"Forbidden":{"description":"The resource is outside the authenticated workspace, or the API key holder lacks the required brand read/write permission.","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"NotFound":{"description":"The requested resource was not found.","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"ValidationError":{"description":"Request validation failed.","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"validation_error","message":"Request validation failed","details":{}}}}}},"RateLimited":{"description":"Too many requests. Wait `Retry-After` seconds, then retry.","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"},"Retry-After":{"$ref":"#/components/headers/RetryAfter"},"RateLimit-Policy":{"$ref":"#/components/headers/RateLimitPolicy"},"RateLimit":{"$ref":"#/components/headers/RateLimit"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"rate_limited","message":"Too many requests. Try again later."}}}}},"MethodNotAllowed":{"description":"HTTP method is not allowed for this endpoint.","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"InternalError":{"description":"Unexpected server error.","headers":{"Cache-Control":{"$ref":"#/components/headers/CacheControl"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"error":{"code":"internal_error","message":"An error occurred"}}}}},"InvalidArgument":{"description":"Missing or invalid request data.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinksErrorResponse"},"examples":{"default":{"value":{"error":"invalid-argument","message":"brandId is required"}}}}}},"Unauthenticated":{"description":"API key is missing or invalid.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinksErrorResponse"},"examples":{"default":{"value":{"error":"unauthenticated","message":"Invalid API key"}}}}}},"PermissionDenied":{"description":"Plan is not allowed, billing profile is missing where required, or the brand is not owned by the effective workspace.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinksErrorResponse"},"examples":{"default":{"value":{"error":"permission-denied","message":"Unauthorized access to brand"}}}}}},"ShareLinksNotFound":{"description":"Brand or share link was not found.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinksErrorResponse"},"examples":{"default":{"value":{"error":"not-found","message":"Share link not found"}}}}}},"FailedPrecondition":{"description":"Request violates plan rules, tab rules, active-link limits, or extension-window rules.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinksErrorResponse"},"examples":{"default":{"value":{"error":"failed-precondition","message":"Maximum of 4 active share links per brand are allowed on your plan."}}}}}},"TooManyRequests":{"description":"Request was rate limited.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinksErrorResponse"},"examples":{"default":{"value":{"error":"too-many-requests","message":"Too many requests"}}}}}},"Internal":{"description":"Unexpected backend error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ShareLinksErrorResponse"},"examples":{"default":{"value":{"error":"internal","message":"Internal error"}}}}}}},"schemas":{"SuccessEnvelope":{"type":"object","required":["success","data"],"properties":{"success":{"type":"boolean","const":true},"data":{"type":"object"},"warnings":{"type":"array","description":"Non-blocking advisory messages. Present (and non-empty) when the request contained fields the endpoint does not recognize, or (on /search-terms-report) when an accepted filter value could not be resolved — e.g. a `selectedTopic` value that is not a known topic ID or name for the brand. Unknown fields are silently stripped and do NOT change behaviour, so a warning most commonly means a date filter was ignored and the request fell back to the default preset window. Known unsupported aliases (e.g. `startDate`, `endDate`, `from`, `to`, `granularity`, `period`) include a \"Did you mean …\" hint pointing at the supported field (`isoStartDate`/`isoEndDate`/`timeFrame`/`aggregation`). Omitted entirely when there are no warnings.","items":{"type":"string"},"example":["Ignored unrecognized field 'startDate'. Did you mean 'isoStartDate'? Falling back to the default reporting window."]}}},"ErrorResponse":{"type":"object","required":["success","error"],"properties":{"success":{"type":"boolean","const":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}},"additionalProperties":true},"warnings":{"type":"array","description":"Same unrecognized-field advisories as the success envelope. Present on handler error responses when the request contained ignored fields. Omitted when empty.","items":{"type":"string"}}},"additionalProperties":false},"FilterValue":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Filter value. Use `all` for no filtering, or pass one or more exact values."},"TimeFrame":{"type":"string","description":"Preset window when custom dates are omitted, matching the Brand Details date-picker range (default 7d). Trailing-average snapshot mapping (same as Brand Details charts and POST /v1/metrics/report when showLastRunMetrics is false): 24h/7d → snapshotH24 (24-hour average), 30d → snapshotD7 (7-day average), 3m/1y → snapshotD30 (30-day average). Raw latest: showLastRunMetrics true → lastRunMetrics. With isoStartDate/isoEndDate: on /report this still selects that snapshot (custom dates are the execution window only); on /search-terms-report it is ignored for metrics (range length infers a timeFrame, then the same mapping); on /sentiment it selects the live competitor-allowlist snapshot family (non-shifted: 24h→H24, 7d→D7, else D30 — Sentiment tab, not /report); on /citations it selects timestampFormat; on /shopping and /ads custom dates select the window.","enum":["24h","7d","30d","3m","1y"]},"Aggregation":{"type":"string","description":"Chart bucket size on /report (hourly, daily, weekly, monthly). Brand Details equivalent: the Aggregation row in the date picker. Not the trailing-average window — that is timeFrame (one window down) plus showLastRunMetrics.","enum":["hourly","daily","weekly","monthly"]},"ReportingRequestBase":{"type":"object","required":["brandId"],"properties":{"brandId":{"type":"string","description":"Brand to report on."},"timeFrame":{"$ref":"#/components/schemas/TimeFrame"},"periodOffset":{"type":"integer","default":0},"isoStartDate":{"type":"string","description":"Custom range start. Must be paired with isoEndDate. Selects the execution/citation/shopping window. Does not fully replace timeFrame: on /report the trailing-average snapshot still uses timeFrame (same one-window-down mapping as Brand Details); on /citations timestampFormat; on /sentiment the live competitor-allowlist snapshot family (non-shifted, Sentiment tab). Sending only one of the pair, an invalid ISO value, or a start after end returns 400 bad_request."},"isoEndDate":{"type":"string","description":"Custom range end. Must be paired with isoStartDate. Selects the execution/citation/shopping window. Does not fully replace timeFrame: on /report the trailing-average snapshot still uses timeFrame (same one-window-down mapping as Brand Details); on /citations timestampFormat; on /sentiment the live competitor-allowlist snapshot family (non-shifted, Sentiment tab). Sending only one of the pair, an invalid ISO value, or a start after end returns 400 bad_request."},"selectedTopic":{"$ref":"#/components/schemas/FilterValue"},"selectedTags":{"$ref":"#/components/schemas/FilterValue"},"selectedEngine":{"$ref":"#/components/schemas/FilterValue"},"selectedQuery":{"$ref":"#/components/schemas/FilterValue"}},"additionalProperties":true,"description":"Common reporting request fields. The schema permits additional properties, but the API ignores any property not defined here (or in the endpoint-specific extension) — ignored fields are reported back in the response's `warnings[]` array. In particular, `topicId` and `aiSearchEngines` are NOT request fields; use `selectedTopic` and `selectedEngine`."},"MetricsReportRequest":{"allOf":[{"$ref":"#/components/schemas/ReportingRequestBase"},{"type":"object","properties":{"aggregation":{"$ref":"#/components/schemas/Aggregation"},"includeNotFoundExecutions":{"type":"boolean"},"showLastRunMetrics":{"type":"boolean","description":"Brand Details Smoothing control. false (default) = Trailing average, using the timeFrame snapshot mapping (24h/7d → snapshotH24, 30d → snapshotD7, 3m/1y → snapshotD30). true = Raw latest (lastRunMetrics), ignoring that mapping."},"userTimezone":{"type":"string","example":"Europe/Berlin"}},"additionalProperties":true}]},"SearchTermsReportRequest":{"allOf":[{"$ref":"#/components/schemas/ReportingRequestBase"},{"type":"object","properties":{"searchTermId":{"type":"string","description":"Single search-term ID filter. Only this endpoint accepts it; on every other reporting endpoint it is ignored (reported in `warnings[]`), so filter those by exact query text with selectedQuery."},"includeAnswerTexts":{"type":"boolean"}},"additionalProperties":true}],"description":"Request body for POST /v1/metrics/search-terms-report. Metrics always come from each search term's latest stored snapshot using the same one-window-down mapping as Brand Details / /report: without custom dates, 24h/7d → snapshotH24, 30d → snapshotD7, 3m/1y → snapshotD30 (snapshotD7 fallback). When isoStartDate/isoEndDate are set, range length infers timeFrame (≤1d → 24h, >1 and ≤7d → 7d, >7 and ≤30d → 30d, >30 and ≤90d → 3m, >90d → 1y) then that frame selects the array; request timeFrame is ignored for metrics. Custom dates and periodOffset constrain answerTexts only. Check each term's lastSnapshotAt for freshness and use /report for metrics over an exact historical range. On this endpoint selectedTopic accepts a topic ID, a case-insensitive topic name, or `_orphaned`; values resolving to none of these are flagged via the response's `warnings[]` array."},"SentimentRequest":{"allOf":[{"$ref":"#/components/schemas/ReportingRequestBase"},{"type":"object","properties":{"deduplicated":{"type":"boolean"}},"additionalProperties":true}]},"CitationsRequest":{"allOf":[{"$ref":"#/components/schemas/ReportingRequestBase"},{"type":"object","properties":{"deduplicated":{"type":"boolean"},"uncapped":{"type":"boolean","description":"Bypasses the default 5,000 unique-URL detail cap for API callers. Check paginationInfo.responseTrimmed for final response-size trimming."}},"additionalProperties":true}]},"ShoppingRequest":{"allOf":[{"$ref":"#/components/schemas/ReportingRequestBase"},{"type":"object","properties":{"tagFilterMode":{"type":"string","enum":["contains","does_not_contain"]},"selectedBrandMode":{"type":"string","enum":["all","branded","non-branded"]},"aggregationLevel":{"type":"string","enum":["hourly","daily","weekly","monthly"],"description":"Rebuckets series, runSeries, and buyboxWinnersByDay. Shopping source data is day-granular, so hourly matches daily."},"itemLimit":{"type":"integer","minimum":1,"description":"Override default item cap of 200. Ignored when uncapped is true."},"providerLimit":{"type":"integer","minimum":1,"description":"Override default provider cap of 100. Ignored when uncapped is true."},"uncapped":{"type":"boolean","description":"When true, return all items and providers with no top-N cap."}},"additionalProperties":true}]},"AdsRequest":{"allOf":[{"$ref":"#/components/schemas/ReportingRequestBase"},{"type":"object","properties":{"tagFilterMode":{"type":"string","enum":["contains","does_not_contain"]},"selectedBrandMode":{"type":"string","enum":["all","branded","non-branded"]},"aggregationLevel":{"type":"string","enum":["hourly","daily","weekly","monthly"],"description":"Rebuckets adsByDay. Shopping source data is day-granular, so hourly matches daily."},"advertiserLimit":{"type":"integer","minimum":1,"description":"Override default advertiser cap of 100. Ignored when uncapped is true."},"uncapped":{"type":"boolean","description":"When true, return all advertisers with no top-N cap."}},"additionalProperties":true}]},"SourcesRequest":{"allOf":[{"$ref":"#/components/schemas/ReportingRequestBase"},{"type":"object","properties":{"tagFilterMode":{"type":"string","enum":["contains","does_not_contain"]},"selectedBrandMode":{"type":"string","enum":["all","branded","non-branded"]},"domainLimit":{"type":"integer","minimum":1,"description":"Override default domain cap of 100. Ignored when uncapped is true."},"termLimit":{"type":"integer","minimum":1,"description":"Override default term cap of 200. Ignored when uncapped is true."},"uncapped":{"type":"boolean","description":"When true, return all domains and terms with no top-N cap."}},"additionalProperties":true}]},"FanoutRequest":{"allOf":[{"$ref":"#/components/schemas/ReportingRequestBase"},{"type":"object","properties":{"tagFilterMode":{"type":"string","enum":["contains","does_not_contain"]},"selectedBrandMode":{"type":"string","enum":["all","branded","non-branded"]},"queryLimit":{"type":"integer","minimum":1,"description":"Override default query cap of 200. Ignored when uncapped is true."},"siteDomainLimit":{"type":"integer","minimum":1,"description":"Override default site-domain cap of 50. Ignored when uncapped is true."},"uncapped":{"type":"boolean","description":"When true, return all queries and site domains with no top-N cap."}},"additionalProperties":true}]},"ShoppingOwnProvider":{"type":"object","properties":{"provider":{"type":"string"},"domain":{"type":"string"},"appearances":{"type":"number"},"detectedRuns":{"type":"number"},"avgRank":{"type":"number"},"detectionRate":{"type":"number"},"visibilityScore":{"type":"number"},"itemsCount":{"type":"number"}},"additionalProperties":true},"ShoppingSummary":{"type":"object","properties":{"totalRuns":{"type":"number"},"totalRunsWithShopping":{"type":"number"},"shoppingDetectionRate":{"type":"number"},"itemCount":{"type":"integer"},"providerCount":{"type":"integer"},"ownProvider":{"oneOf":[{"$ref":"#/components/schemas/ShoppingOwnProvider"},{"type":"null"}]}},"additionalProperties":true},"ShoppingItem":{"type":"object","properties":{"url":{"type":"string"},"title":{"type":"string"},"appearances":{"type":"number"},"detectedRuns":{"type":"number"},"avgRank":{"type":"number"},"detectionRate":{"type":"number"},"visibilityScore":{"type":"number"},"avgPrice":{"type":"number"},"currency":{"type":"string"},"providerStats":{"type":"array","items":{"type":"object","additionalProperties":true}},"searchTerms":{"type":"array","items":{"type":"object","additionalProperties":true}}},"additionalProperties":true},"ShoppingProvider":{"type":"object","properties":{"provider":{"type":"string"},"domain":{"type":"string"},"isOwnBrand":{"type":"boolean"},"appearances":{"type":"number"},"detectedRuns":{"type":"number"},"avgRank":{"type":"number"},"detectionRate":{"type":"number"},"visibilityScore":{"type":"number"},"itemsCount":{"type":"number"}},"additionalProperties":true},"ShoppingSeriesPoint":{"type":"object","properties":{"date":{"type":"string"},"entityType":{"type":"string"},"entityId":{"type":"string"},"mentions":{"type":"number"},"avgPrice":{"type":"number"},"avgRating":{"type":"number"},"avgReviews":{"type":"number"}},"additionalProperties":true},"ShoppingRunSeriesPoint":{"type":"object","properties":{"date":{"type":"string"},"runsWithShopping":{"type":"number"},"runsWithoutShopping":{"type":"number"},"totalRuns":{"type":"number"}},"additionalProperties":true},"ShoppingBuyboxDay":{"type":"object","properties":{"date":{"type":"string"},"providers":{"type":"array","items":{"type":"object","properties":{"provider":{"type":"string"},"wins":{"type":"number"}},"additionalProperties":true}}},"additionalProperties":true},"ShoppingEngineBreakdown":{"type":"object","properties":{"engine":{"type":"string"},"totalRuns":{"type":"number"},"runsWithShopping":{"type":"number"},"itemCount":{"type":"integer"},"providerCount":{"type":"integer"},"topItems":{"type":"array","items":{"type":"object","additionalProperties":true}},"topProviders":{"type":"array","items":{"type":"object","additionalProperties":true}},"ownedProvider":{"type":"object","additionalProperties":true},"ownedProviders":{"type":"array","items":{"type":"object","additionalProperties":true}},"ownedDetectedRuns":{"type":"integer","description":"Distinct shopping runs where any owned merchant appeared. Not the sum of per-provider detectedRuns."}},"additionalProperties":true},"ShoppingSearchTermSummary":{"type":"object","additionalProperties":true},"ShoppingTruncated":{"type":"object","properties":{"items":{"type":"boolean"},"providers":{"type":"boolean"},"responseSizeLimited":{"type":"boolean"}},"additionalProperties":true},"ShoppingReportData":{"type":"object","properties":{"timeFrame":{"type":"string"},"aggregationLevel":{"type":"string","enum":["hourly","daily","weekly","monthly"]},"requestedDateRange":{"$ref":"#/components/schemas/RequestedDateRange"},"summary":{"$ref":"#/components/schemas/ShoppingSummary"},"items":{"type":"array","items":{"$ref":"#/components/schemas/ShoppingItem"}},"providers":{"type":"array","items":{"$ref":"#/components/schemas/ShoppingProvider"}},"series":{"type":"array","items":{"$ref":"#/components/schemas/ShoppingSeriesPoint"}},"runSeries":{"type":"array","items":{"$ref":"#/components/schemas/ShoppingRunSeriesPoint"}},"buyboxWinnersByDay":{"type":"array","items":{"$ref":"#/components/schemas/ShoppingBuyboxDay"}},"engineBreakdown":{"type":"array","items":{"$ref":"#/components/schemas/ShoppingEngineBreakdown"}},"searchTermsSummary":{"type":"array","items":{"$ref":"#/components/schemas/ShoppingSearchTermSummary"}},"truncated":{"$ref":"#/components/schemas/ShoppingTruncated"}}},"ShoppingResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ShoppingReportData"},"warnings":{"type":"array","items":{"type":"string"}}}}]},"AdsOwnAdvertiser":{"type":"object","properties":{"advertiser":{"type":"string"},"domain":{"type":"string"},"appearances":{"type":"number"},"detectedRuns":{"type":"number"},"appearanceRate":{"type":"number"}},"additionalProperties":true},"AdsSummary":{"type":"object","properties":{"totalRunsWithAds":{"type":"number"},"totalAdEligibleRuns":{"type":"number"},"advertiserCount":{"type":"integer"},"ownAppearances":{"type":"number"},"ownShareOfVoice":{"type":"number"},"ownAdvertiser":{"oneOf":[{"$ref":"#/components/schemas/AdsOwnAdvertiser"},{"type":"null"}]}},"additionalProperties":true},"AdsPlacement":{"type":"object","properties":{"advertiser":{"type":"string"},"domain":{"type":"string"},"isOwnBrand":{"type":"boolean"},"appearances":{"type":"number"},"detectedRuns":{"type":"number"},"totalRuns":{"type":"number"},"appearanceRate":{"type":"number"},"engines":{"type":"array","items":{"type":"object","additionalProperties":true}},"searchTerms":{"type":"array","items":{"type":"object","additionalProperties":true}},"samples":{"type":"array","items":{"type":"object","additionalProperties":true}}},"additionalProperties":true},"AdsByDay":{"type":"object","properties":{"date":{"type":"string"},"totalRunsWithAds":{"type":"number"},"advertisers":{"type":"array","items":{"type":"object","additionalProperties":true}}},"additionalProperties":true},"AdsTruncated":{"type":"object","properties":{"advertisers":{"type":"boolean"},"responseSizeLimited":{"type":"boolean"}},"additionalProperties":true},"AdsReportData":{"type":"object","properties":{"timeFrame":{"type":"string"},"aggregationLevel":{"type":"string","enum":["hourly","daily","weekly","monthly"]},"requestedDateRange":{"$ref":"#/components/schemas/RequestedDateRange"},"summary":{"$ref":"#/components/schemas/AdsSummary"},"adPlacements":{"type":"array","items":{"$ref":"#/components/schemas/AdsPlacement"}},"adsByDay":{"type":"array","items":{"$ref":"#/components/schemas/AdsByDay"}},"truncated":{"$ref":"#/components/schemas/AdsTruncated"}}},"AdsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/AdsReportData"},"warnings":{"type":"array","items":{"type":"string"}}}}]},"SourcesReportData":{"type":"object","properties":{"timeFrame":{"type":"string"},"requestedDateRange":{"$ref":"#/components/schemas/RequestedDateRange"},"summary":{"type":"object","additionalProperties":true},"domains":{"type":"array","items":{"type":"object","additionalProperties":true}},"terms":{"type":"array","items":{"type":"object","additionalProperties":true}},"truncated":{"type":"object","properties":{"domains":{"type":"boolean"},"terms":{"type":"boolean"},"responseSizeLimited":{"type":"boolean"}},"additionalProperties":true}}},"SourcesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SourcesReportData"},"warnings":{"type":"array","items":{"type":"string"}}}}]},"FanoutReportData":{"type":"object","properties":{"timeFrame":{"type":"string"},"requestedDateRange":{"$ref":"#/components/schemas/RequestedDateRange"},"language":{"type":"string"},"ownedDomains":{"type":"array","items":{"type":"string"}},"aggregatedAtISO":{"type":"string"},"kpis":{"type":"object","additionalProperties":true},"previousKpis":{"type":"object","additionalProperties":true},"kpisDelta":{"type":"object","additionalProperties":true},"previousWindow":{"type":"object","additionalProperties":true},"summary":{"type":"object","additionalProperties":true},"fanouts":{"type":"array","items":{"type":"object","additionalProperties":true}},"dailyActivity":{"type":"array","items":{"type":"object","additionalProperties":true}},"siteDomainLeaderboard":{"type":"array","items":{"type":"object","additionalProperties":true}},"appendixInsights":{"type":"object","additionalProperties":true},"truncated":{"type":"object","properties":{"queries":{"type":"boolean"},"siteDomains":{"type":"boolean"},"responseSizeLimited":{"type":"boolean"}},"additionalProperties":true}}},"FanoutResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/FanoutReportData"},"warnings":{"type":"array","items":{"type":"string"}}}}]},"LocalResultsRequest":{"allOf":[{"$ref":"#/components/schemas/ReportingRequestBase"},{"type":"object","properties":{"tagFilterMode":{"type":"string","enum":["contains","does_not_contain"]},"selectedBrandMode":{"type":"string","enum":["all","branded","non-branded"]},"aggregationLevel":{"type":"string","enum":["hourly","daily","weekly","monthly"],"default":"daily","description":"Bucket size of the trend points. hourly returns the raw hourly points; weekly and monthly roll the points up."},"periodOffset":{"type":"integer","minimum":0,"maximum":10000,"default":0,"description":"Moves the preset window into the past. 0 is the current period. Negative values are rejected with 422."},"placeLimit":{"type":"integer","minimum":1,"maximum":1000,"description":"Override the default cap of 50 places (maximum 1000, larger values return 422, also when uncapped is true). Own-brand places are always kept in addition to the cap. Not applied when uncapped is true."},"promptLimit":{"type":"integer","minimum":1,"maximum":1000,"description":"Override the default cap of 100 prompt coverage rows (maximum 1000, larger values return 422, also when uncapped is true). Not applied when uncapped is true."},"uncapped":{"type":"boolean","description":"When true, return all places and prompt coverage rows with no top-N cap. Then check truncated.responseSizeLimited."}},"additionalProperties":true}],"description":"selectedEngine is narrowed to map-capable engines (chatgpt_gui, google_ai_mode_gui, bing_copilot_gui, perplexity_gui, google_ai_overview, google_gemini_gui). When none of the requested engines is map-capable, all map-capable engines are used. Windows are calendar days in UTC; with isoStartDate/isoEndDate both values are truncated to their UTC day and isoEndDate is the inclusive last day."},"LocalResultsKpi":{"type":"object","description":"Current value, previous-window value and the change. previous and delta are null when comparisonInsufficient is true. All three fields are null for a window without eligible runs. For share, avgPosition, detectionRate and top3Rate they are also null when the window has eligible runs but no map results (previous and delta are null when the previous window has none).","properties":{"value":{"type":["number","null"]},"previous":{"type":["number","null"]},"delta":{"type":["number","null"]}},"required":["value","previous","delta"]},"LocalResultsWindowCounts":{"type":"object","properties":{"executions":{"type":"integer","description":"Map-bearing run snapshots that Share, Avg. Position and Top 3 are computed over."},"eligibleRuns":{"type":"integer","description":"Runs on map-capable engines. Denominator of mapResultsRate; equals the sum of the per-engine eligibleRuns."},"mapBearingRuns":{"type":"integer","description":"Eligible runs that returned at least one map result. Numerator of mapResultsRate; equals the sum of the per-engine mapBearingRuns."},"uniqueQueries":{"type":"integer"},"activeDays":{"type":"integer"}},"required":["executions","eligibleRuns","mapBearingRuns","uniqueQueries","activeDays"]},"LocalResultsEngineRow":{"type":"object","properties":{"engine":{"type":"string"},"status":{"type":"string","enum":["ready","no_maps","low_sample"]},"eligibleRuns":{"type":"integer"},"mapBearingRuns":{"type":"integer"},"mapResultsRate":{"type":["number","null"],"description":"Map-bearing runs over eligible runs, in percent."},"packVolumeShare":{"type":["number","null"]},"avgPackSize":{"type":["number","null"]},"detectionRate":{"type":["number","null"],"description":"Share of map-bearing runs in which an own-brand place appears, in percent. null when the engine has eligible runs but no map results."},"reach":{"type":["number","null"],"description":"Share of eligible runs in which an own-brand place appears in the map results, in percent. 0 when the engine has eligible runs but no map results."},"share":{"type":["number","null"],"description":"Own-brand share of place appearances, in percent. null when the engine has eligible runs but no map results."},"avgPosition":{"type":["number","null"],"description":"1-based, only over runs where the brand is found. Lower is better. null when the engine has no map results."},"top3Rate":{"type":["number","null"],"description":"Share of map-bearing runs in which the brand ranks in the top three, in percent. null when the engine has eligible runs but no map results."},"ownShareRank":{"type":["integer","null"]},"leader":{"type":["object","null"],"properties":{"name":{"type":"string"},"share":{"type":"number"}}},"mainRival":{"type":["object","null"],"properties":{"name":{"type":"string"},"basis":{"type":["string","null"]},"aboveCount":{"type":"integer"},"sharedPacks":{"type":"integer"}}},"rating":{"type":["object","null"],"description":"Only present when the data supports a rating comparison, otherwise null.","properties":{"own":{"type":["number","null"]},"packMedian":{"type":["number","null"]}}},"reviews":{"type":["object","null"],"description":"Only present when the data supports a review comparison, otherwise null.","properties":{"own":{"type":["number","null"]},"packMedian":{"type":["number","null"]}}},"comparisonInsufficient":{"type":"boolean"},"deltas":{"type":"object","properties":{"detectionRate":{"type":["number","null"]},"share":{"type":["number","null"]},"avgPosition":{"type":["number","null"]},"top3Rate":{"type":["number","null"]}}}},"required":["engine","status","eligibleRuns","mapBearingRuns","detectionRate","comparisonInsufficient","deltas"]},"LocalResultsPlace":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"isOwnBrand":{"type":"boolean"},"classification":{"type":"string","enum":["own_brand","competitor","other"],"description":"A place with classification other can still carry competitorKind discovered."},"competitorKind":{"type":["string","null"],"description":"tracked or discovered for rival places, null for own places and for other places that are neither. A place with classification other can come with competitorKind discovered.","enum":["tracked","discovered",null]},"share":{"type":["number","null"]},"detectionRate":{"type":"number"},"avgPosition":{"type":["number","null"]},"bestPosition":{"type":["number","null"]},"top3Rate":{"type":["number","null"]},"avgPositionDelta":{"type":["number","null"]},"engines":{"type":"array","items":{"type":"string"}},"rating":{"type":["number","null"]},"reviewCount":{"type":["number","null"]},"category":{"type":["string","null"]},"city":{"type":["string","null"]},"countryCode":{"type":["string","null"]},"mapsUrl":{"type":["string","null"]},"websiteUrl":{"type":["string","null"]},"firstSeen":{"type":["string","null"],"format":"date-time"},"lastSeen":{"type":["string","null"],"format":"date-time"}},"required":["key","name","isOwnBrand","classification","detectionRate","engines"],"description":"Places are sorted by Share (ties by detection rate, then name). Coordinates, addresses, phone numbers, images and review texts are not returned."},"LocalResultsTrendMetrics":{"type":"object","properties":{"detectionRate":{"type":"number"},"avgPosition":{"type":["number","null"]},"top3Rate":{"type":"number"}},"required":["detectionRate","avgPosition","top3Rate"]},"LocalResultsTrendPoint":{"type":"object","properties":{"date":{"type":"string"},"sampleRuns":{"type":"integer"},"own":{"$ref":"#/components/schemas/LocalResultsTrendMetrics"},"places":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/LocalResultsTrendMetrics"},"description":"Keyed by trend.entities[].key for the places other than the own brand."}},"required":["date","sampleRuns","own","places"]},"LocalResultsPromptCell":{"type":"object","properties":{"eligibleRuns":{"type":"integer"},"mapBearingRuns":{"type":"integer"},"detectionRate":{"type":["number","null"]},"avgPosition":{"type":["number","null"]},"leader":{"type":["string","null"]}},"required":["eligibleRuns","mapBearingRuns"]},"LocalResultsPromptRow":{"type":"object","properties":{"searchTermId":{"type":"string"},"prompt":{"type":"string"},"opportunityScore":{"type":"number"},"cells":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/LocalResultsPromptCell"},"description":"Keyed by engine id."}},"required":["searchTermId","prompt","opportunityScore","cells"]},"LocalResultsInsight":{"type":"object","properties":{"id":{"type":"string"},"ruleId":{"type":"string"},"severity":{"type":"string","enum":["positive","negative","neutral","warning"]},"title":{"type":"string"},"body":{"type":"string"},"confidence":{"type":"string","enum":["high","medium","low"]},"sampleSize":{"type":"integer"}},"required":["id","ruleId","severity","title","body","confidence","sampleSize"]},"LocalResultsTruncated":{"type":"object","properties":{"places":{"type":"boolean"},"promptCoverage":{"type":"boolean"},"responseSizeLimited":{"type":"boolean"}},"required":["places","promptCoverage","responseSizeLimited"]},"LocalResultsReportData":{"type":"object","properties":{"brandId":{"type":"string"},"timeFrame":{"$ref":"#/components/schemas/TimeFrame"},"aggregationLevel":{"type":"string","enum":["hourly","daily","weekly","monthly"]},"requestedDateRange":{"type":"object","properties":{"source":{"type":"string","enum":["custom","timeFrame"]},"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time"}}},"comparisonWindow":{"type":["object","null"],"properties":{"startDate":{"type":"string"},"endDateExclusive":{"type":"string"},"label":{"type":"string"}}},"aggregatedAt":{"type":"string","format":"date-time"},"engines":{"type":"array","items":{"type":"string"}},"window":{"type":"object","properties":{"current":{"$ref":"#/components/schemas/LocalResultsWindowCounts"},"previous":{"oneOf":[{"$ref":"#/components/schemas/LocalResultsWindowCounts"},{"type":"null"}]}}},"kpis":{"type":"object","properties":{"comparisonInsufficient":{"type":"boolean"},"share":{"$ref":"#/components/schemas/LocalResultsKpi"},"avgPosition":{"$ref":"#/components/schemas/LocalResultsKpi"},"detectionRate":{"$ref":"#/components/schemas/LocalResultsKpi"},"top3Rate":{"$ref":"#/components/schemas/LocalResultsKpi"},"mapResultsRate":{"type":["number","null"],"description":"Map-bearing runs over eligible runs, in percent. null when the window has no eligible runs, 0 when it has eligible runs but no map results."},"reach":{"type":["number","null"],"description":"Share of all eligible runs in which one of the brand's places appears in the map results, in percent (detectionRate x mapBearingRuns / eligibleRuns). null when the window has no eligible runs, 0 when it has eligible runs but no map results."},"closestCompetitor":{"type":["object","null"],"properties":{"name":{"type":"string"},"gap":{"type":["number","null"]}}}}},"engineBreakdown":{"type":"array","items":{"$ref":"#/components/schemas/LocalResultsEngineRow"}},"places":{"type":"array","items":{"$ref":"#/components/schemas/LocalResultsPlace"}},"trend":{"type":"object","properties":{"entities":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string"},"name":{"type":"string"},"isOwnBrand":{"type":"boolean"},"competitorKind":{"type":["string","null"]}}}},"points":{"type":"array","items":{"$ref":"#/components/schemas/LocalResultsTrendPoint"}}},"description":"The own brand plus up to 5 places by Share."},"promptCoverage":{"type":"object","properties":{"engines":{"type":"array","items":{"type":"string"}},"rows":{"type":"array","items":{"$ref":"#/components/schemas/LocalResultsPromptRow"}}}},"insights":{"type":"array","items":{"$ref":"#/components/schemas/LocalResultsInsight"},"description":"Up to 10 insights, highest priority first."},"summary":{"type":"object","properties":{"placeCount":{"type":"integer"},"trackedCompetitorPlaceCount":{"type":"integer"},"discoveredPlaceCount":{"type":"integer"},"promptCount":{"type":"integer"}}},"truncated":{"$ref":"#/components/schemas/LocalResultsTruncated"}},"required":["brandId","timeFrame","aggregationLevel","requestedDateRange","engines","window","kpis","engineBreakdown","places","trend","promptCoverage","insights","summary","truncated"]},"LocalResultsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LocalResultsReportData"},"warnings":{"type":"array","items":{"type":"string"}}}}]},"FollowUpFormsRequest":{"type":"object","required":["brandId"],"properties":{"brandId":{"type":"string","description":"Brand to report on."},"timeFrame":{"$ref":"#/components/schemas/TimeFrame"},"periodOffset":{"type":"integer","minimum":0,"maximum":10000,"default":0,"description":"Shifts a preset window back by whole windows. Ignored when isoStartDate and isoEndDate are sent."},"isoStartDate":{"type":"string","description":"First UTC calendar day of a custom range. Must be paired with isoEndDate. Sending only one of the pair, an invalid ISO value, or a start after end returns 400 bad_request."},"isoEndDate":{"type":"string","description":"Last UTC calendar day of a custom range (inclusive). Must be paired with isoStartDate."},"selectedTopic":{"$ref":"#/components/schemas/FilterValue"},"selectedTags":{"$ref":"#/components/schemas/FilterValue"},"selectedQuery":{"$ref":"#/components/schemas/FilterValue"},"tagFilterMode":{"type":"string","enum":["contains","does_not_contain"]},"selectedBrandMode":{"type":"string","enum":["all","branded","non-branded"]},"aggregationLevel":{"type":"string","enum":["auto","hourly","daily","weekly","monthly"],"default":"auto","description":"Series bucket size. auto uses daily buckets for windows of 45 days or fewer and ISO weeks (Monday start) beyond, like the Follow-up Forms tab. hourly behaves like daily because the source data is day-granular."},"questionLimit":{"type":"integer","minimum":1,"maximum":1000,"description":"Override the default cap of 50 questions. Above 1000 returns 422 validation_error. Ignored when uncapped is true."},"promptLimit":{"type":"integer","minimum":1,"maximum":1000,"description":"Override the default cap of 25 follow-up prompts. Above 1000 returns 422 validation_error. Ignored when uncapped is true."},"termLimit":{"type":"integer","minimum":1,"maximum":1000,"description":"Override the default cap of 100 prompts in the per-prompt list. Above 1000 returns 422 validation_error. Ignored when uncapped is true."},"uncapped":{"type":"boolean","description":"When true, return all questions, follow-up prompts and prompts with no top-N cap. Check truncated.responseSizeLimited afterwards."}},"additionalProperties":true,"description":"Request body for the follow-up forms report. The report covers ChatGPT only, so there is no engine filter: a selectedEngine field is ignored and reported in warnings[]."},"FollowUpFormsWindowCounts":{"type":"object","required":["totalRuns","checkedRuns","uncheckedRuns","runsWithForm","formRate","uniqueQuestions","avgQuestionsPerForm","termsChecked","termsWithForms","totalTerms"],"properties":{"totalRuns":{"type":"integer","description":"ChatGPT runs in the window."},"checkedRuns":{"type":"integer","description":"Runs where the follow-up form check could be applied. Denominator of formRate."},"uncheckedRuns":{"type":"integer","description":"Runs without a usable check (before tracking started or without stored data). Excluded from formRate."},"runsWithForm":{"type":"integer","description":"Checked runs where ChatGPT asked follow-up questions before answering."},"formRate":{"type":["number","null"],"minimum":0,"maximum":1,"description":"runsWithForm / checkedRuns, rounded to 4 decimals. null when checkedRuns is 0."},"uniqueQuestions":{"type":"integer"},"avgQuestionsPerForm":{"type":"number","description":"Average number of questions per form, rounded to 2 decimals."},"termsChecked":{"type":"integer","description":"Prompts with at least one checked run."},"termsWithForms":{"type":"integer","description":"Prompts with at least one run with a form."},"totalTerms":{"type":"integer","description":"Prompts in scope after filters."}}},"FollowUpFormsWindow":{"type":"object","required":["current","previous","previousStatus","previousDateRange","formRateDeltaPp"],"properties":{"current":{"$ref":"#/components/schemas/FollowUpFormsWindowCounts"},"previous":{"oneOf":[{"$ref":"#/components/schemas/FollowUpFormsWindowCounts"},{"type":"null"}],"description":"Counts for the window of the same length immediately before the current one. null when previousStatus is before_rollout."},"previousStatus":{"type":"string","enum":["ok","before_rollout","no_checked_runs"],"description":"before_rollout: the previous window ends before tracking started and was not fetched. no_checked_runs: it was fetched but nothing could be checked."},"previousDateRange":{"type":"object","required":["startDate","endDate"],"properties":{"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"}}},"formRateDeltaPp":{"type":["number","null"],"description":"(current formRate - previous formRate) * 100, one decimal. null when either rate is null."}}},"FollowUpFormsSeriesPoint":{"type":"object","required":["bucket","startDate","endDate","totalRuns","checkedRuns","runsWithForm","formRate","beforeRollout"],"properties":{"bucket":{"type":"string","description":"Bucket key: the first UTC day of the bucket (a Monday for weekly buckets, the 1st for monthly buckets). Buckets are labelled by their week or month start, which can fall before the window start; only data inside the window is counted."},"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"},"totalRuns":{"type":"integer"},"checkedRuns":{"type":"integer"},"runsWithForm":{"type":"integer"},"formRate":{"type":["number","null"],"minimum":0,"maximum":1,"description":"null when nothing was checked in the bucket, including days before tracking started. Never 0 for those days."},"beforeRollout":{"type":"boolean","description":"True when the bucket lies entirely before tracking started."}}},"FollowUpFormsOption":{"type":"object","required":["key","label","appearances","share","defaultSelected","defaultShare"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"appearances":{"type":"integer","description":"Times this option was shown."},"share":{"type":"number","description":"Share of the question's appearances that showed this option (0 to 1)."},"defaultSelected":{"type":"integer","description":"Times this option was pre-selected."},"defaultShare":{"type":"number","description":"Share of the question's appearances where this option was pre-selected (0 to 1)."}}},"FollowUpFormsQuestion":{"type":"object","required":["key","label","type","appearances","formShare","firstSeen","lastSeen","termCount","defaultShare","defaultOption","options"],"properties":{"key":{"type":"string","description":"Normalized question text."},"label":{"type":"string"},"type":{"type":"string","description":"Form control type, for example radio."},"appearances":{"type":"integer"},"formShare":{"type":"number","description":"appearances / runsWithForm (0 to 1)."},"firstSeen":{"type":"string","format":"date-time"},"lastSeen":{"type":"string","format":"date-time"},"termCount":{"type":"integer","description":"Prompts where the question appeared."},"defaultShare":{"type":"number","description":"Share of appearances with any option pre-selected (0 to 1)."},"defaultOption":{"oneOf":[{"type":"object","required":["key","label","defaultSelected","defaultShare"],"properties":{"key":{"type":"string"},"label":{"type":"string"},"defaultSelected":{"type":"integer"},"defaultShare":{"type":"number"}}},{"type":"null"}],"description":"Most often pre-selected option. null when no option was ever pre-selected."},"options":{"type":"array","items":{"$ref":"#/components/schemas/FollowUpFormsOption"},"description":"Not capped. Sorted by pre-selected count, then appearances, then label."}},"description":"Per-term lists, recent runs and daily appearance series are not included."},"FollowUpFormsPrompt":{"type":"object","required":["followUpPrompt","count","lastExecutionId","lastSearchTermId","lastExecutedAtISO"],"properties":{"followUpPrompt":{"type":"string","description":"Follow-up prompt template, with slots in braces."},"count":{"type":"integer"},"lastExecutionId":{"type":["string","null"]},"lastSearchTermId":{"type":["string","null"]},"lastExecutedAtISO":{"type":["string","null"],"format":"date-time"},"slots":{"type":"object","additionalProperties":{"type":"object","properties":{"label":{"type":"string"},"options":{"type":"array","items":{"type":"string"}},"value":{"type":"string"}}}}}},"FollowUpFormsTerm":{"type":"object","required":["searchTermId","label","checkedRuns","runsWithForm","formRate","tags","topicId","topicName"],"properties":{"searchTermId":{"type":"string"},"label":{"type":"string"},"checkedRuns":{"type":"integer"},"runsWithForm":{"type":"integer"},"formRate":{"type":["number","null"],"minimum":0,"maximum":1,"description":"null when no run of the prompt was checked."},"tags":{"type":"array","items":{"type":"string"}},"topicId":{"type":["string","null"]},"topicName":{"type":["string","null"]}}},"FollowUpFormsTruncated":{"type":"object","required":["questions","prompts","terms","responseSizeLimited"],"properties":{"questions":{"type":"boolean"},"prompts":{"type":"boolean"},"terms":{"type":"boolean"},"responseSizeLimited":{"type":"boolean","description":"True when arrays were trimmed to fit the response size ceiling."}}},"FollowUpFormsReportData":{"type":"object","required":["brandId","engine","timeFrame","requestedDateRange","aggregationLevel","aggregatedAtISO","trackingStartedAt","includesPreRollout","window","series","questions","followUpPrompts","terms","summary","truncated"],"properties":{"brandId":{"type":"string"},"engine":{"type":"string","enum":["chatgpt_gui"]},"timeFrame":{"oneOf":[{"$ref":"#/components/schemas/TimeFrame"},{"type":"null"}],"description":"null when custom dates were sent."},"requestedDateRange":{"type":"object","required":["source","startDate","endDate"],"properties":{"source":{"type":"string","enum":["timeFrame","custom"]},"startDate":{"type":"string","format":"date"},"endDate":{"type":"string","format":"date"}}},"aggregationLevel":{"type":"string","enum":["daily","weekly","monthly"],"description":"Resolved series bucket size."},"aggregatedAtISO":{"type":["string","null"],"format":"date-time"},"trackingStartedAt":{"type":"string","format":"date-time","description":"Exact start of follow-up form tracking (2026-10-09T22:02:00.000Z, UTC). Runs before it count as unchecked and do not affect the rate."},"includesPreRollout":{"type":"boolean","description":"True when the window starts before tracking started."},"window":{"$ref":"#/components/schemas/FollowUpFormsWindow"},"series":{"type":"array","items":{"$ref":"#/components/schemas/FollowUpFormsSeriesPoint"},"description":"Every bucket of the window, including empty and pre-tracking buckets."},"questions":{"type":"array","items":{"$ref":"#/components/schemas/FollowUpFormsQuestion"}},"followUpPrompts":{"type":"array","items":{"$ref":"#/components/schemas/FollowUpFormsPrompt"}},"terms":{"type":"array","items":{"$ref":"#/components/schemas/FollowUpFormsTerm"}},"summary":{"type":"object","required":["questionCount","promptCount","termCount"],"properties":{"questionCount":{"type":"integer"},"promptCount":{"type":"integer"},"termCount":{"type":"integer"}},"description":"Totals before caps are applied."},"truncated":{"$ref":"#/components/schemas/FollowUpFormsTruncated"}}},"FollowUpFormsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/FollowUpFormsReportData"},"warnings":{"type":"array","items":{"type":"string"}}}}]},"ExecutionsRequest":{"type":"object","required":["searchTermIds"],"additionalProperties":false,"properties":{"searchTermIds":{"type":"array","minItems":1,"maxItems":500,"items":{"type":"string","minLength":1},"description":"Search term document IDs. Duplicates are ignored. Every ID must belong to the authenticated workspace and pass brand read access."},"isoStartDate":{"type":"string","description":"Inclusive range start. Must be paired with isoEndDate. Date-only values are treated as the start of that UTC day."},"isoEndDate":{"type":"string","description":"Inclusive range end. Must be paired with isoStartDate. Date-only values are treated as the end of that UTC day."},"limit":{"type":"integer","minimum":1,"maximum":500,"default":100,"description":"Page size. Max 500 normally; max 50 when includeRawProviderResponse is true."},"cursor":{"type":"string","description":"Opaque cursor from a previous nextCursor. Omit on the first page."},"includeRawProviderResponse":{"type":"boolean","default":false,"description":"When true, include rawProviderResponse (and savedAt). Keep false unless you need the full provider payload."},"includeMetrics":{"type":"boolean","default":false,"description":"When true, attach visibilityScores (latest / 24h / 7d / 30d) from the linked searchTermMetrics document."}}},"ExecutionVisibilityScores":{"type":"object","properties":{"latest":{"type":["number","null"]},"h24":{"type":["number","null"]},"d7":{"type":["number","null"]},"d30":{"type":["number","null"]}},"additionalProperties":false},"ExecutionRecord":{"type":"object","required":["id","searchTermId","term","topicName","tags"],"properties":{"id":{"type":"string"},"searchTermId":{"type":"string"},"term":{"type":"string","description":"Search term text at read time."},"topicName":{"type":"string"},"tags":{"type":"array","items":{"type":"string"}},"query":{"type":"string"},"engine":{"$ref":"#/components/schemas/AiSearchEngineId"},"executedAt":{"type":"string","format":"date-time","description":"ISO-8601 timestamp."},"response":{"type":"string"},"myBrand":{"type":"string"},"brandRef":{"type":["string","null"]},"citations":{"type":"array","items":{"type":"string"}},"companies":{"type":"array","items":{"type":"object","additionalProperties":true}},"visibilityScores":{"$ref":"#/components/schemas/ExecutionVisibilityScores"},"rawProviderResponse":{"description":"Present only when includeRawProviderResponse is true."}},"additionalProperties":true,"description":"Raw searchTermExecutions fields with Firestore Timestamps converted to ISO strings. usage and htmlSnapshotPath are never returned."},"ExecutionsPage":{"type":"object","required":["executions","nextCursor","hasMore"],"properties":{"executions":{"type":"array","items":{"$ref":"#/components/schemas/ExecutionRecord"}},"nextCursor":{"type":["string","null"],"description":"Pass as cursor on the next request. Null when hasMore is false."},"hasMore":{"type":"boolean"},"totalEstimate":{"type":"integer","description":"Approximate total matching executions. Present on the first page only."}},"additionalProperties":false},"ExecutionsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ExecutionsPage"},"warnings":{"type":"array","items":{"type":"string"}}}}]},"MetricsReportResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/MetricsReportData"}}}]},"MetricsReportData":{"type":"object","properties":{"ownBrandMetrics":{"$ref":"#/components/schemas/BrandMetrics"},"competitorMetrics":{"type":"array","items":{"$ref":"#/components/schemas/CompetitorMetrics"}},"competitorTimeSeriesData":{"type":"object","additionalProperties":true},"preselectionWhitelist":{"type":"array","items":{"type":"string"}},"preselectionBlacklist":{"type":"array","items":{"type":"string"}},"manualWhitelist":{"type":"array","items":{"type":"string"}},"manualBlacklist":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"OwnBrandHistoricalSlice":{"type":"object","description":"Parallel arrays for one aggregation level. All numeric/boolean series align with timestamps[]. Own-brand history may include competitor-only days as ranking 0 for chart continuity; topic/engine series do not invent synthetic ranking buckets for execution-only days.","properties":{"timestamps":{"type":"array","items":{"type":"string","format":"date-time"}},"visibilityScore":{"type":"array","items":{"type":"number"}},"sentiment":{"type":"array","items":{"type":"number"}},"mentions":{"type":"array","items":{"type":"number"}},"sources":{"type":"array","items":{"type":"number"}},"citations":{"type":"array","items":{"type":"number"}},"citationCounts":{"type":"array","items":{"type":"number"},"description":"Legacy URL-level citationCount series (for competitive share charts)."},"avgPosition":{"type":"array","items":{"type":"number"}},"detectionRate":{"type":"array","items":{"type":"number"}},"top3":{"type":"array","items":{"type":"number"}},"executionsAnalyzed":{"type":"array","items":{"type":"integer"},"description":"Per-bucket count of non-obsolete searchTermMetrics docs (1:1 with chats/runs analyzed). Aligned with timestamps[]. Not reduced by includeNotFoundExecutions."},"brandNotFound":{"type":"array","items":{"type":"boolean"}}},"additionalProperties":true},"TopicMetricsSeries":{"type":"object","description":"Per-topic timeseries for one aggregation level. Ranking arrays omit synthetic execution-only buckets; executionsAnalyzed[] is still present on ranking buckets and aligns with timestamps[].","properties":{"topicId":{"type":"string"},"topicName":{"type":"string"},"timestamps":{"type":"array","items":{"type":"string","format":"date-time"}},"visibilityScore":{"type":"array","items":{"type":"number"}},"sentiment":{"type":"array","items":{"type":"number"}},"avgPosition":{"type":"array","items":{"type":"number"}},"detectionRate":{"type":"array","items":{"type":"number"}},"top3":{"type":"array","items":{"type":"number"}},"mentions":{"type":"array","items":{"type":"number"}},"sources":{"type":"array","items":{"type":"number"}},"citations":{"type":"array","items":{"type":"number"}},"executionsAnalyzed":{"type":"array","items":{"type":"integer"},"description":"Per-bucket executions analyzed for this topic scope; aligned with timestamps[]."},"brandNotFound":{"type":"array","items":{"type":"boolean"}}},"additionalProperties":true},"EngineMetricsSeries":{"type":"object","description":"Per-engine timeseries for one aggregation level. Same ranking/execution semantics as TopicMetricsSeries.","properties":{"engineId":{"type":"string"},"engineName":{"type":"string"},"timestamps":{"type":"array","items":{"type":"string","format":"date-time"}},"visibilityScore":{"type":"array","items":{"type":"number"}},"sentiment":{"type":"array","items":{"type":"number"}},"avgPosition":{"type":"array","items":{"type":"number"}},"detectionRate":{"type":"array","items":{"type":"number"}},"top3":{"type":"array","items":{"type":"number"}},"mentions":{"type":"array","items":{"type":"number"}},"sources":{"type":"array","items":{"type":"number"}},"citations":{"type":"array","items":{"type":"number"}},"executionsAnalyzed":{"type":"array","items":{"type":"integer"},"description":"Per-bucket executions analyzed for this engine scope; aligned with timestamps[]."},"brandNotFound":{"type":"array","items":{"type":"boolean"}}},"additionalProperties":true},"BrandMetricsTrends":{"type":"object","description":"Delta between the last two buckets of the selected aggregation. Ranking trends skip trailing buckets with no own-brand ranking observation; executionsAnalyzed uses the last two series buckets.","properties":{"visibilityScore":{"type":"number"},"sentiment":{"type":"number"},"mentions":{"type":"number"},"sources":{"type":"number"},"citations":{"type":"number"},"avgPosition":{"type":"number"},"detectionRate":{"type":"number"},"top3":{"type":"number"},"executionsAnalyzed":{"type":"number","description":"Delta of per-bucket executionsAnalyzed between the last two aggregation buckets."}},"additionalProperties":true},"BrandMetrics":{"type":"object","properties":{"visibilityScore":{"type":"number","description":"Latest ranking-observed visibility score for the selected aggregation (0-100)."},"sentiment":{"type":"number"},"mentions":{"type":"integer","description":"Sum of per-bucket mentions over the selected window."},"sources":{"type":"integer"},"citations":{"type":"integer","description":"Sum of per-bucket citations over the selected window."},"avgPosition":{"type":"number"},"detectionRate":{"type":"number"},"top3":{"type":"number"},"validMetricsCount":{"type":"integer","description":"Number of aggregation buckets in the selected timeseries (not execution count)."},"executionsAnalyzed":{"type":"integer","description":"Total chats/runs analyzed in the report window — counted as non-obsolete searchTermMetrics docs for the same filtered search-term scope (1:1 with executions; same corpus as report metrics). Sum of historicalData[aggregation].executionsAnalyzed[]. Baseline for mentions/citations; not reduced by includeNotFoundExecutions or showLastRunMetrics. Distinct from validMetricsCount and search-term executionsAmount."},"trends":{"$ref":"#/components/schemas/BrandMetricsTrends"},"historicalData":{"type":"object","description":"Own-brand parallel arrays by aggregation level. Only the requested aggregation is typically populated; each slice includes executionsAnalyzed[] aligned with timestamps[].","properties":{"hourly":{"$ref":"#/components/schemas/OwnBrandHistoricalSlice"},"daily":{"$ref":"#/components/schemas/OwnBrandHistoricalSlice"},"weekly":{"$ref":"#/components/schemas/OwnBrandHistoricalSlice"},"monthly":{"$ref":"#/components/schemas/OwnBrandHistoricalSlice"}},"additionalProperties":true},"topicMetricsData":{"type":"object","description":"Per-topic timeseries by aggregation level. Ranking series omit synthetic execution-only buckets so latestValue is not overwritten by empty averages.","properties":{"hourly":{"type":"array","items":{"$ref":"#/components/schemas/TopicMetricsSeries"}},"daily":{"type":"array","items":{"$ref":"#/components/schemas/TopicMetricsSeries"}},"weekly":{"type":"array","items":{"$ref":"#/components/schemas/TopicMetricsSeries"}},"monthly":{"type":"array","items":{"$ref":"#/components/schemas/TopicMetricsSeries"}}},"additionalProperties":true},"engineMetricsData":{"type":"object","description":"Per-engine timeseries by aggregation level. Same ranking/execution semantics as topicMetricsData.","properties":{"hourly":{"type":"array","items":{"$ref":"#/components/schemas/EngineMetricsSeries"}},"daily":{"type":"array","items":{"$ref":"#/components/schemas/EngineMetricsSeries"}},"weekly":{"type":"array","items":{"$ref":"#/components/schemas/EngineMetricsSeries"}},"monthly":{"type":"array","items":{"$ref":"#/components/schemas/EngineMetricsSeries"}}},"additionalProperties":true}},"additionalProperties":true},"CompetitorMetrics":{"type":"object","properties":{"name":{"type":"string"},"isOwnBrand":{"type":"boolean"},"latestValue":{"type":"number"},"trend":{"type":"number"},"variations":{"type":"array","items":{"type":"string"}},"visibilityScore":{"type":"number"},"latestRank":{"type":"number"},"avgRank":{"type":"number"},"avgSentiment":{"type":"number"},"appearances":{"type":"integer"},"citationCount":{"type":"integer"},"detectionRate":{"type":"number"},"top3":{"type":"number"},"validMetricsCount":{"type":"integer"}},"additionalProperties":true},"SearchTermsReportResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"timeFrame":{"type":"string"},"requestedDateRange":{"$ref":"#/components/schemas/RequestedDateRange"},"searchTerms":{"type":"array","items":{"$ref":"#/components/schemas/SearchTermReportItem"}}},"additionalProperties":true}}}]},"RequestedDateRange":{"type":"object","properties":{"source":{"type":"string"},"startDate":{"type":"string","format":"date-time"},"endDate":{"type":"string","format":"date-time"}},"additionalProperties":true},"SearchTermReportItem":{"type":"object","properties":{"searchTermId":{"type":"string"},"query":{"type":"string"},"aiSearchEngines":{"type":"array","description":"Engine IDs stored on the search term. Only the first element is the effective engine used for execution.","items":{"$ref":"#/components/schemas/AiSearchEngineId"}},"topic":{"$ref":"#/components/schemas/TopicRef"},"tags":{"type":"array","items":{"type":"string"}},"status":{"type":"string"},"interval":{"type":"string"},"region":{"type":"string","description":"Lowercase ISO-3166 alpha-2 country code (e.g. us, gb, de). Must be a known country code and supported by the primary engine. Unknown or unsupported regions return 400 invalid_region. Omit to use the engine default."},"websearch":{"type":"boolean"},"lastSnapshotAt":{"type":"string","format":"date-time"},"ownBrand":{"$ref":"#/components/schemas/SearchTermBrandMetrics"},"competitors":{"type":"array","items":{"$ref":"#/components/schemas/SearchTermBrandMetrics"}},"answerTexts":{"type":"array","items":{"$ref":"#/components/schemas/AnswerText"}}},"additionalProperties":true},"SearchTermBrandMetrics":{"type":"object","properties":{"name":{"type":"string"},"visibilityScore":{"type":"number"},"avgRank":{"type":"number"},"detectionRate":{"type":"number"},"top3":{"type":"number"},"citationCount":{"type":"integer"},"avgSentiment":{"type":"number"}},"additionalProperties":true},"AnswerText":{"type":"object","properties":{"executionId":{"type":"string"},"executedAt":{"type":"string","format":"date-time"},"engine":{"type":"string"},"answerText":{"type":"string"}},"additionalProperties":true},"SentimentResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"brandSentiments":{"type":"array","items":{"$ref":"#/components/schemas/CompanySentiment"}},"companySentiments":{"type":"array","items":{"$ref":"#/components/schemas/CompanySentiment"}}},"additionalProperties":true}}}]},"CompanySentiment":{"type":"object","properties":{"name":{"type":"string"},"isOwnBrand":{"type":"boolean"},"totalSentimentScore":{"type":"number"},"sentimentCount":{"type":"integer"},"avgSentiment":{"type":"number"},"positiveCount":{"type":"integer"},"neutralCount":{"type":"integer"},"negativeCount":{"type":"integer"},"executionCount":{"type":"integer"},"hasWebGrounding":{"type":"boolean"},"hasTrainingData":{"type":"boolean"},"webGroundingKeywords":{"type":"object","additionalProperties":true},"trainingDataKeywords":{"type":"object","additionalProperties":true},"webGroundingSentimentByEngine":{"type":"object","additionalProperties":true},"trainingDataSentimentByEngine":{"type":"object","additionalProperties":true}},"additionalProperties":true},"CitationsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CitationsData"}}}]},"CitationsData":{"type":"object","properties":{"totalCitations":{"type":"integer"},"uniqueCitations":{"type":"integer"},"domainSummary":{"type":"object","additionalProperties":true},"citationsByDomain":{"type":"array","items":{"type":"object","properties":{"domain":{"type":"string"},"occurrences":{"type":"integer"},"citations":{"type":"array","items":{"type":"object","properties":{"url":{"type":"string"},"normalizedUrl":{"type":"string"},"occurrences":{"type":"integer"},"counts":{"type":"object","additionalProperties":{"type":"integer"},"description":"Bucket date (e.g. '2026-05-01') to appearance count. Present for timeFrames of 7d and longer."},"countsGranularity":{"type":"string","enum":["daily","weekly"],"description":"Bucket size used by `counts`."},"relevantSeenAt":{"type":"array","items":{"type":"string","format":"date-time"},"description":"Raw appearance timestamps. Present only for timeFrame 24h (timestampFormat 'full')."},"firstSeenAt":{"type":"string","format":"date-time"},"lastSeenAt":{"type":"string","format":"date-time"},"category":{"type":"string"}},"additionalProperties":true}}},"additionalProperties":true}},"timestampFormat":{"type":"string","enum":["full","daily","weekly"],"description":"How per-URL time data is encoded: 'full' (timeFrame 24h) means raw `relevantSeenAt` timestamps; 7d/30d use 'daily' and 3m/1y use 'weekly' bucketed `counts` per URL."}},"additionalProperties":true},"BrandCreateRequest":{"type":"object","required":["name","url"],"properties":{"name":{"type":"string","minLength":1},"url":{"type":"string","minLength":1},"description":{"type":"string"},"additionalDomains":{"type":"array","maxItems":15,"items":{"type":"string"}},"defaultCountry":{"type":"string","default":"us"},"defaultLanguage":{"type":"string","default":"en"},"insightsEnabled":{"type":"boolean","default":true},"brandInfo":{"type":"array","items":{"$ref":"#/components/schemas/BrandInfoInput"}},"syncSchedules":{"anyOf":[{"$ref":"#/components/schemas/SyncSchedules"},{"type":"null"}]}},"additionalProperties":false},"BrandPatchRequest":{"type":"object","properties":{"name":{"type":"string"},"url":{"type":"string"},"description":{"type":"string"},"additionalDomains":{"type":"array","maxItems":15,"items":{"type":"string"}},"defaultCountry":{"type":"string"},"defaultLanguage":{"type":"string"},"insightsEnabled":{"type":"boolean"},"brandInfo":{"type":"array","items":{"$ref":"#/components/schemas/BrandInfoInput"}},"syncSchedules":{"anyOf":[{"$ref":"#/components/schemas/SyncSchedules"},{"type":"null"}]}},"additionalProperties":false},"BrandAnalysisRunRequest":{"type":"object","properties":{"ownBrandNames":{"type":"array","maxItems":200,"items":{"type":"string","minLength":1},"description":"Optional override for this analysis run. If omitted, the API uses saved brand names from the brand document."}},"additionalProperties":false},"BrandAnalysisRecalculateRequest":{"oneOf":[{"type":"object","required":["searchTermIds"],"properties":{"searchTermIds":{"type":"array","minItems":1,"maxItems":5000,"items":{"type":"string","minLength":1},"description":"Search term ids to recalculate. Each value is trimmed and must contain at least one non-whitespace character. A whitespace-only value fails validation with 422."}},"additionalProperties":false},{"type":"object","required":["allSearchTerms"],"properties":{"allSearchTerms":{"type":"boolean","enum":[true],"description":"Recalculate every search term on the brand. Mutually exclusive with searchTermIds."}},"additionalProperties":false}]},"BrandAnalysisLabelsRequest":{"oneOf":[{"type":"object","required":["action","brandName"],"properties":{"action":{"type":"string","enum":["mark_own_brand","unmark_own_brand"],"description":"`mark_own_brand` sets Your Brand on a false negative. `unmark_own_brand` clears Your Brand on a false positive."},"brandName":{"type":"string","minLength":1,"description":"Finding name from `results` or `negatives`. Matching is case-insensitive. Mutually exclusive with `all`."}},"additionalProperties":false},{"type":"object","required":["action","all"],"properties":{"action":{"type":"string","enum":["mark_own_brand","unmark_own_brand"]},"all":{"type":"boolean","enum":[true],"description":"Apply the action to every current finding of that kind. Mutually exclusive with brandName."}},"additionalProperties":false}]},"BrandAnalysisLabelsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["action","applied","brandNames","updatedDocuments","affectedSearchTermIds"],"properties":{"action":{"type":"string","enum":["mark_own_brand","unmark_own_brand"]},"applied":{"type":"boolean","description":"False when brandName is not a current finding of that kind. True for all: true even when the finding list is empty."},"brandNames":{"type":"array","items":{"type":"string"},"description":"Finding names the server wrote. Empty when nothing matched."},"updatedDocuments":{"type":"integer"},"affectedSearchTermIds":{"type":"array","items":{"type":"string"},"description":"Search term ids whose executions or citations were updated. Pass these to recalculate."}},"additionalProperties":false}}}]},"BrandAnalysisBrandNameRequest":{"type":"object","required":["brandName"],"properties":{"brandName":{"type":"string","minLength":1,"description":"Brand name or wildcard pattern (for example `Dyson*`)."}},"additionalProperties":false},"BrandAnalysisResultItem":{"type":"object","required":["brandName","executionEntries","searchTermEntries","executionMatches","searchTermMatches"],"properties":{"brandName":{"type":"string"},"executionEntries":{"type":"integer"},"searchTermEntries":{"type":"integer"},"executionMatches":{"type":"object","description":"Execution-document matches keyed by execution document ID. Array items are company indices; negative values encode foundCompetitors indices as `-(index + 1)`.","additionalProperties":{"type":"array","items":{"type":"integer"}}},"searchTermMatches":{"type":"object","description":"Search-term citation matches keyed by searchTerm document ID.","additionalProperties":{"type":"array","items":{"type":"object","required":["domain","brandIndex"],"properties":{"domain":{"type":"string"},"brandIndex":{"type":"integer"}},"additionalProperties":false}}}},"additionalProperties":false},"BrandAnalysisResultsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["ownBrandNames","results","negatives","stats"],"properties":{"ownBrandNames":{"type":"array","items":{"type":"string"}},"results":{"type":"array","items":{"$ref":"#/components/schemas/BrandAnalysisResultItem"}},"negatives":{"type":"array","items":{"$ref":"#/components/schemas/BrandAnalysisResultItem"}},"stats":{"type":"object","required":["executionDocsProcessed","searchTermDocsProcessed"],"properties":{"executionDocsProcessed":{"type":"integer"},"searchTermDocsProcessed":{"type":"integer"}},"additionalProperties":false}},"additionalProperties":false}}}]},"BrandAnalysisRecalculateResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["success","message"],"properties":{"success":{"type":"boolean"},"message":{"type":"string"}},"additionalProperties":false}}}]},"BrandAnalysisBrandNamesResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["id","brandNames"],"properties":{"id":{"type":"string"},"brandNames":{"type":"array","items":{"type":"string"}},"added":{"type":"boolean"},"removed":{"type":"boolean"}},"additionalProperties":false}}}]},"BrandInfoInput":{"type":"object","properties":{"brands":{"type":"array","items":{"type":"string"}},"products":{"type":"array","items":{"type":"string"}}},"additionalProperties":false},"SyncSchedules":{"type":"object","properties":{"daily":{"anyOf":[{"type":"object","required":["hour"],"properties":{"hour":{"type":"integer","minimum":0,"maximum":23}},"additionalProperties":false},{"type":"null"}]},"weekly":{"anyOf":[{"type":"object","required":["weekday"],"properties":{"weekday":{"type":"string","enum":["mon","tue","wed","thu","fri","sat","sun"]}},"additionalProperties":false},{"type":"null"}]},"monthly":{"anyOf":[{"type":"object","required":["dayOfMonth"],"properties":{"dayOfMonth":{"type":"integer","minimum":1,"maximum":28}},"additionalProperties":false},{"type":"null"}]}},"additionalProperties":false},"BrandListResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["brands"],"properties":{"brands":{"type":"array","items":{"$ref":"#/components/schemas/Brand"}}}}}}]},"Brand":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"brandInfo":{"type":"object","properties":{"names":{"type":"array","items":{"type":"string"}},"productNames":{"type":"array","items":{"type":"string"}},"description":{"type":"string"}},"additionalProperties":true},"description":{"type":"string"},"url":{"type":"string"},"additionalDomains":{"type":"array","items":{"type":"string"}},"createdAt":{"type":"string","format":"date-time"},"operationalTopics":{"type":"array","items":{"$ref":"#/components/schemas/OperationalTopic"}},"operationalSearchTerms":{"type":"array","items":{"$ref":"#/components/schemas/OperationalSearchTerm"}},"defaultCountry":{"type":"string"},"defaultLanguage":{"type":"string"},"syncSchedules":{"$ref":"#/components/schemas/SyncSchedules"}},"additionalProperties":true},"OperationalTopic":{"type":"object","properties":{"topicId":{"type":"string"},"name":{"type":"string"},"addedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"OperationalSearchTerm":{"type":"object","properties":{"searchTermId":{"type":"string"}},"additionalProperties":true},"SearchTermCreateRequest":{"type":"object","required":["brandRef","term"],"properties":{"brandRef":{"type":"string"},"term":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["active","inactive"],"default":"inactive"},"aiSearchEngines":{"type":"array","description":"Known non-deprecated engine IDs. Create expands one input row into one created search term per engine. Omit or send [] to use the default [\"perplexity_sonar\"]. Unknown IDs return invalid_engine and deprecated IDs return deprecated_engine.","items":{"$ref":"#/components/schemas/AiSearchEngineId"},"example":["perplexity_gui"],"default":["perplexity_sonar"]},"interval":{"$ref":"#/components/schemas/SearchTermInterval"},"intervalEveryN":{"type":"integer","enum":[1,2],"default":1},"tags":{"type":"array","items":{"type":"string"}},"websearch":{"type":"boolean","default":false},"searchTermTopicRef":{"$ref":"#/components/schemas/SearchTermTopicInput"},"executionLimit":{"type":["number","null"]},"competitors":{"type":"array","items":{}},"region":{"type":["string","null"],"description":"Lowercase ISO-3166 alpha-2 country code (e.g. us, gb, de). Must be a known country code and supported by every requested engine. Unknown or unsupported regions return 400 invalid_region. Omit to use the engine default."},"region_string":{"type":["string","null"]},"language":{"type":["string","null"]}},"additionalProperties":true,"description":"Single search-term create body. aiSearchEngines must use AiSearchEngineId values; deprecated engines are rejected. region must be a known ISO-3166 alpha-2 code supported by every requested engine."},"SearchTermPatchRequest":{"type":"object","properties":{"term":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]},"aiSearchEngines":{"type":"array","description":"Exactly one known engine ID (for example [\"perplexity_gui\"]). More than one engine or an empty array is rejected with 400 validation_error. Unknown engines return 400 invalid_engine and deprecated engines return 400 deprecated_engine. Omit the field when you are not changing the engine; a value identical to the one returned by GET is accepted unchanged, so older search terms that store several engines can still be updated. Switching engines does not create additional search terms.","minItems":1,"items":{"$ref":"#/components/schemas/AiSearchEngineId"},"example":["chatgpt_gui"]},"interval":{"$ref":"#/components/schemas/SearchTermInterval"},"intervalEveryN":{"type":"integer","enum":[1,2]},"websearch":{"type":"boolean"},"searchTermTopicRef":{"$ref":"#/components/schemas/SearchTermTopicInput"},"tags":{"type":"array","items":{"type":"string"}},"region":{"type":"string","description":"Lowercase ISO-3166 alpha-2 country code (e.g. us, gb, de). Must be a known country code and supported by the primary engine. Unknown or unsupported regions return 400 invalid_region. Omit to use the engine default."},"region_string":{"type":"string"},"language":{"type":"string"},"executionLimit":{"type":["number","null"]}},"additionalProperties":false,"description":"Partial search-term update. Patching aiSearchEngines rejects unknown/deprecated engines. Patching region (or engines when a region is already set) rejects unknown/unsupported regions."},"SearchTermInterval":{"type":"string","enum":["hourly","daily","weekly","monthly","manual"]},"SearchTermTopicInput":{"oneOf":[{"type":"string"},{"type":"object","required":["id"],"properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":false},{"type":"null"}]},"SearchTermListResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["searchTerms"],"properties":{"searchTerms":{"type":"array","items":{"$ref":"#/components/schemas/SearchTerm"}}}}}}]},"SearchTerm":{"type":"object","properties":{"id":{"type":"string"},"term":{"type":"string"},"aiSearchEngines":{"type":"array","description":"Engine IDs stored on the search term. Only the first element is the effective engine used for scheduling and execution.","items":{"$ref":"#/components/schemas/AiSearchEngineId"}},"status":{"type":"string"},"executionsAmount":{"type":"integer"},"interval":{"type":"string"},"region":{"type":"string","description":"Lowercase ISO-3166 alpha-2 country code (e.g. us, gb, de). Must be a known country code and supported by the primary engine. Unknown or unsupported regions return 400 invalid_region. Omit to use the engine default."},"websearch":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"lastExecutionTime":{"type":["string","null"],"format":"date-time"},"nextScheduledExecutionTime":{"type":["string","null"],"format":"date-time"},"searchTermTopicRef":{"$ref":"#/components/schemas/TopicRef"}},"additionalProperties":true},"TopicRef":{"type":["object","null"],"properties":{"id":{"type":"string"},"name":{"type":"string"}},"additionalProperties":true},"SearchTermRunResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SearchTermRunSummary"}}}]},"SearchTermRunSummary":{"type":"object","properties":{"success":{"type":"boolean"},"duplicate":{"type":"boolean"},"totalRequested":{"type":"integer"},"successCount":{"type":"integer"},"failureCount":{"type":"integer"},"skippedCount":{"type":"integer"},"results":{"type":"array","items":{"$ref":"#/components/schemas/SearchTermRunResult"}}},"additionalProperties":true},"SearchTermRunResult":{"type":"object","required":["searchTermId","success"],"properties":{"searchTermId":{"type":"string"},"success":{"type":"boolean"},"executionId":{"type":"string"},"error":{"type":"string"}},"additionalProperties":true},"TopicCreateRequest":{"type":"object","required":["name","brandRef"],"properties":{"name":{"type":"string","minLength":1},"brandRef":{"type":"string","minLength":1},"description":{"type":"string"},"keywords":{"type":"string"}},"additionalProperties":true},"TopicPatchRequest":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"keywords":{"type":"string"},"brandRef":{"type":"string"}},"additionalProperties":false},"TopicListResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["topics"],"properties":{"topics":{"type":"array","items":{"$ref":"#/components/schemas/Topic"}}}}}}]},"Topic":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"brandRef":{"type":"string"},"myBrand":{"type":["string","null"]},"createdBy":{"type":"string"},"searchTermIds":{"type":"array","items":{"type":"string"}},"keywords":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}},"additionalProperties":true},"IdResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}},"additionalProperties":true}}}]},"DeletedResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["id","deleted"],"properties":{"id":{"type":"string"},"deleted":{"type":"boolean","const":true}}}}}]},"StatusResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["id","status"],"properties":{"id":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]}}}}}]},"CreditsResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/CreditsData"}}}]},"CreditsData":{"type":"object","properties":{"rankCredits":{"type":"number"},"bonusRankCredits":{"type":"number"},"analysisCredits":{"type":"number"},"promptResearchCredits":{"type":"number"},"creditsInFlight":{"type":"number"},"runway":{"type":"object","description":"Present only when includeRunway=true.","properties":{"estimatedRunwayHours":{"type":"number"},"creditsPerHourAvg":{"type":"number"},"totalCostForNextExecution":{"type":"number"},"nextBilling":{"type":["string","null"],"format":"date-time"},"simulationLimitedByBilling":{"type":"boolean"},"simulationLimitedByHorizon":{"type":"boolean"},"breakdown":{"type":"array","items":{"type":"object","additionalProperties":true}}},"additionalProperties":true},"dashboardRunway":{"type":"object","description":"Present only when includeRunway=true.","additionalProperties":true}},"additionalProperties":true},"AiSearchEngineId":{"type":"string","description":"AI search engine ID. Deprecated engines are rejected on create and when aiSearchEngines is patched. See metrics-api.md Engine IDs for deprecation notes and replacements.","enum":["perplexity_sonar","perplexity_sonar_pro","perplexity_sonar_reasoning","perplexity_sonar_reasoning_pro","openai_gpt-4o","openai_gpt-5","openai_gpt-5_6_terra","openai_gpt-6_1_sol","meta_muse_spark","google_ai_overview","google_gemini_15","google_gemini_20","google_gemini_25","google_gemini_30_flash","google_gemini_38_flash","google_gemini_30_Pro","google_gemini_31_Pro","anthropic_claude_3_5_sonnet","anthropic_claude_3_5_haiku","anthropic_claude_4_5_haiku","anthropic_claude_sonnet_5_5","anthropic_claude_haiku_5_5","deepseek_chat","mistral_large","perplexity_gui","chatgpt_gui","google_ai_mode_gui","google_gemini_gui","xai_grok_gui","bing_copilot_gui"]},"SearchTermBatchCreateRequest":{"type":"object","required":["searchTerms"],"properties":{"searchTerms":{"type":"array","minItems":1,"maxItems":100,"description":"1–100 search terms to create in one request. Validation is all-or-nothing before write. Each row expands into one created search term per requested engine; the expanded total must stay within 100 writes.","items":{"$ref":"#/components/schemas/SearchTermCreateRequest"}}},"additionalProperties":false},"PromptResearchCreateRequest":{"type":"object","required":["input"],"properties":{"input":{"type":"object","required":["segment","region","output_language"],"properties":{"segment":{"type":"string","minLength":1},"region":{"type":"string","minLength":1,"description":"Country or region code."},"output_language":{"type":"string","minLength":1,"description":"Response language code."}},"additionalProperties":false},"provider":{"type":"string","enum":["gemini","gpt5"],"default":"gemini"},"brandId":{"oneOf":[{"type":"string"},{"type":"null"}],"description":"Optional brand context. Must belong to the authenticated workspace when provided."}},"additionalProperties":false},"SearchTermBatchCreateResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["searchTerms"],"properties":{"searchTerms":{"type":"array","items":{"type":"object","required":["id","term"],"properties":{"id":{"type":"string"},"term":{"type":"string"}}}}}}}}]},"PromptResearchRecord":{"type":"object","properties":{"id":{"type":"string"},"userId":{"oneOf":[{"type":"string"},{"type":"null"}]},"brandId":{"oneOf":[{"type":"string"},{"type":"null"}]},"provider":{"oneOf":[{"type":"string"},{"type":"null"}]},"status":{"oneOf":[{"type":"string"},{"type":"null"}]},"input":{"oneOf":[{"type":"object","additionalProperties":true},{"type":"null"}]},"usage":{"oneOf":[{"type":"object","additionalProperties":true},{"type":"null"}]},"durationMs":{"oneOf":[{"type":"number"},{"type":"null"}]},"text":{"oneOf":[{"type":"string"},{"type":"null"}]},"parsed":{},"meta":{},"entities":{"type":"array","items":{}},"intents_ranked":{"type":"array","items":{}},"createdAt":{"oneOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"updatedAt":{"oneOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"additionalProperties":true},"PromptResearchCreateResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"oneOf":[{"type":"string"},{"type":"null"}]},"status":{"type":"string"},"provider":{"type":"string"},"input":{"type":"object","additionalProperties":true},"usage":{"oneOf":[{"type":"object","additionalProperties":true},{"type":"null"}]},"text":{"type":"string"},"durationMs":{"oneOf":[{"type":"number"},{"type":"null"}]},"brandId":{"oneOf":[{"type":"string"},{"type":"null"}]}},"additionalProperties":true}}}]},"PromptResearchListResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"promptResearches":{"type":"array","items":{"$ref":"#/components/schemas/PromptResearchRecord"}}},"additionalProperties":false}}}]},"SearchTermBatchPatchItem":{"type":"object","required":["searchTermId"],"properties":{"searchTermId":{"type":"string","description":"Search term ID to update."},"term":{"type":"string"},"description":{"type":"string"},"status":{"type":"string","enum":["active","inactive"]},"aiSearchEngines":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/AiSearchEngineId"}},"interval":{"$ref":"#/components/schemas/SearchTermInterval"},"intervalEveryN":{"type":"integer","enum":[1,2]},"websearch":{"type":"boolean"},"searchTermTopicRef":{"$ref":"#/components/schemas/SearchTermTopicInput"},"tags":{"type":"array","items":{"type":"string"}},"region":{"type":["string","null"]},"region_string":{"type":["string","null"]},"language":{"type":["string","null"]},"executionLimit":{"type":["number","null"]}},"additionalProperties":false},"PromptResearchGetResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/PromptResearchRecord"}}}]},"SearchTermBatchPatchRequest":{"type":"object","required":["updates"],"properties":{"updates":{"type":"array","minItems":1,"maxItems":100,"description":"1–100 search-term patches in one request. Validation is all-or-nothing before write.","items":{"$ref":"#/components/schemas/SearchTermBatchPatchItem"}}},"additionalProperties":false},"SearchTermBatchPatchResponse":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","required":["searchTerms"],"properties":{"searchTerms":{"type":"array","items":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}}}}}}}]},"ShareLink":{"type":"object","properties":{"id":{"type":"string","description":"Share link ID."},"token":{"type":"string","description":"Public viewer token embedded in the URL."},"brandId":{"type":"string","description":"Shared brand ID."},"createdAt":{"type":["string","null"],"format":"date-time"},"expiresAt":{"type":["string","null"],"format":"date-time","description":"ISO expiry timestamp, or null for no-expiry links."},"disabled":{"type":"boolean"},"allowedTabs":{"$ref":"#/components/schemas/AllowedTabs"},"initialFilters":{"$ref":"#/components/schemas/ShareLinkFilters"},"lockFilters":{"type":"boolean"},"views":{"type":"integer","minimum":0},"url":{"type":"string","format":"uri","description":"Full read-only viewer URL."},"whitelabel":{"type":"boolean","description":"Whether the link uses the whitelabel viewer route."}},"required":["id","token","brandId","createdAt","expiresAt","disabled","lockFilters","views","whitelabel"],"additionalProperties":true},"BrandWithShareLinks":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"createdAt":{"type":["string","null"],"format":"date-time"},"activeLinks":{"type":"array","items":{"$ref":"#/components/schemas/ShareLink"}},"inactiveLinks":{"type":"array","items":{"$ref":"#/components/schemas/ShareLink"}}},"required":["id","name","createdAt","activeLinks","inactiveLinks"],"additionalProperties":false},"ListBrandsResponse":{"type":"object","properties":{"brands":{"type":"array","items":{"$ref":"#/components/schemas/BrandWithShareLinks"}}},"required":["brands"],"additionalProperties":false},"ListShareLinksResponse":{"type":"object","properties":{"links":{"type":"array","items":{"$ref":"#/components/schemas/ShareLink"}}},"required":["links"],"additionalProperties":false},"AllowedTab":{"type":"string","enum":["Dashboard","Competitors","Recommendations","Citations","Query Fanout","Shopping","Sentiment","Custom Dashboard","Topics","Search Terms"]},"AllowedTabs":{"type":"array","items":{"$ref":"#/components/schemas/AllowedTab"},"uniqueItems":true},"CreateShareLinkRequest":{"type":"object","properties":{"brandId":{"type":"string","description":"Brand ID to share. The brand must belong to the effective workspace."},"allowedTabs":{"$ref":"#/components/schemas/AllowedTabs"},"initialFilters":{"$ref":"#/components/schemas/ShareLinkFilters"},"lockFilters":{"type":"boolean","description":"When true, viewers cannot change the initial filters."},"noExpiry":{"type":"boolean","description":"When true, stores `expiresAt` as null."},"expiresAt":{"type":["string","null"],"format":"date-time","description":"Optional explicit expiry. Ignored when `noExpiry` is true."},"whitelabel":{"type":"boolean","description":"Honored only for Enterprise-tier accounts."},"dashboardViewId":{"type":"string","description":"Saved dashboard view ID used when `allowedTabs` includes `Custom Dashboard`. Honored only for Pro-tier and higher accounts and unavailable when `whitelabel_keyword` is in effect."}},"required":["brandId"],"additionalProperties":false},"UpdateShareLinkRequest":{"type":"object","properties":{"allowedTabs":{"$ref":"#/components/schemas/AllowedTabs"},"initialFilters":{"$ref":"#/components/schemas/ShareLinkFilters"},"lockFilters":{"type":"boolean"},"disabled":{"type":"boolean"},"expiresAt":{"type":["string","null"],"format":"date-time","description":"Set to null for no-expiry."},"dashboardViewId":{"type":"string","description":"Saved dashboard view ID. Send an empty string to clear it. Honored only for Pro-tier and higher accounts and unavailable when `whitelabel_keyword` is in effect."}},"additionalProperties":false},"ExtendShareLinkRequest":{"type":"object","properties":{"reactivate":{"type":"boolean","description":"When true, re-enables the link and adds 30 days while respecting active-link limits."}},"additionalProperties":false},"ExtendShareLinkResponse":{"type":"object","properties":{"id":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"disabled":{"type":"boolean"},"url":{"type":"string","format":"uri"}},"required":["id","expiresAt","disabled"],"additionalProperties":false},"DeleteShareLinkResponse":{"type":"object","properties":{"success":{"type":"boolean","const":true}},"required":["success"],"additionalProperties":false},"ShareLinkFilters":{"type":"object","properties":{"timeFrame":{"type":"string","enum":["24h","7d","30d","3m","1y"]},"selectedAggregation":{"type":"string","enum":["hourly","daily","weekly","monthly"]},"selectedTopic":{"$ref":"#/components/schemas/FilterSelection"},"selectedEngine":{"$ref":"#/components/schemas/FilterSelection"},"selectedQuery":{"$ref":"#/components/schemas/FilterSelection"},"selectedFilters":{"$ref":"#/components/schemas/SelectedFilters"},"includeNotFoundExecutions":{"type":"boolean"},"showLastRunMetrics":{"type":"boolean"},"periodOffset":{"type":"integer","minimum":0},"customStartISO":{"type":"string","format":"date-time"},"customEndISO":{"type":"string","format":"date-time"},"customRangeMode":{"type":"string"},"customRangeTz":{"type":"string","description":"IANA timezone for custom range handling."}},"additionalProperties":true},"FilterSelection":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Human-readable display value, `all`, or an array of display values where supported."},"SelectedFilters":{"type":"object","properties":{"topics":{"$ref":"#/components/schemas/FilterSelection"},"engines":{"$ref":"#/components/schemas/FilterSelection"},"queries":{"$ref":"#/components/schemas/FilterSelection"}},"additionalProperties":false},"ShareLinksErrorResponse":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}},"required":["error","message"],"additionalProperties":true},"OAuthBearerError":{"type":"object","description":"The error body of a 401 from the MCP server, named by RFC 6750 section 3.1.","required":["error"],"properties":{"error":{"type":"string","description":"Machine-readable code such as `invalid_token`.","examples":["invalid_token"]},"error_description":{"type":"string","description":"Human-readable explanation."}},"additionalProperties":true},"JsonRpcErrorResponse":{"type":"object","description":"A JSON-RPC 2.0 error response.","required":["jsonrpc","error"],"properties":{"jsonrpc":{"type":"string","enum":["2.0"]},"id":{"type":["string","integer","null"]},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"integer","description":"JSON-RPC error code, for example -32601 for an unknown method."},"message":{"type":"string"},"data":{}}}}}}}}