{"openapi":"3.1.0","info":{"title":"3RD","version":"1.0.0","description":"3RD shows how ChatGPT, Gemini, Google AI Overviews, Copilot, Perplexity and Claude describe a brand, why they choose a competitor, and what to change next. The Export API paths below are the canonical spec from https://app.get3rd.com/api/export/v1/openapi.json, served here so an agent that only reads get3rd.com can find them. Paths on https://www.get3rd.com describe this host. Export API: Read-only access to a brand's AI-visibility data: daily visibility by model and market, the URLs the models cite and the Citation Share they add up to, daily brand sentiment, the Recommended rate, and daily visibility for each tracked competitor.\n\nBuilt for loading into a BI tool, a warehouse, or a data-normalization service. Every endpoint is a `GET`, returns JSON, and never writes.\n\n**Authentication.** Send an export API key in the `X-API-Key` header. Keys are created by an organization owner or admin under Settings → Looker Studio in the 3RD app, are shown once, and can be revoked at any time (revocation is immediate). The organization needs an active paid plan. An unscoped key reads every active brand in the organization that issued it. A key limited to specific brands reads only those. A key stops working once the owner or admin who created it leaves the organization or loses that role.\n\n**Pagination.** Responses are cursor-paginated at 1000 rows per page. Follow `pagination.nextCursor` until `pagination.hasMore` is false. Do not construct cursors yourself — the encoding is not part of this contract.\n\n**History.** The window is capped by the organization's plan (lite: no access, pro: 90 days, agency: 180 days, enterprise: full history). A request for a wider window is silently clamped rather than rejected, so read `meta.fromDate` to see what was actually returned.\n\n**Rate limit.** 100 requests per minute. The budget is the API key sent in `X-API-Key` — every request using that key shares the budget regardless of IP or User-Agent. Exceeding it returns 429.\n\n**Ad performance is not on this API.** Paid-placement data is currently available only through the MCP server, reads live from the ad platform with a fixed 30-day window, and cannot be backfilled."},"servers":[{"url":"https://www.get3rd.com","description":"3RD marketing site and discovery"},{"url":"https://app.get3rd.com/api/export/v1","description":"3RD Export API"}],"paths":{"/v1/product":{"servers":[{"url":"https://www.get3rd.com"}],"get":{"operationId":"getProduct","summary":"Describe 3RD for an agent","description":"Public description of 3RD: what it measures, which MCP server and Export API to call, and how to authenticate.","responses":{"200":{"description":"Product description","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Product"}}}},"429":{"description":"Rate limit exceeded","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1":{"servers":[{"url":"https://www.get3rd.com"}],"get":{"operationId":"getApiChallenge","summary":"Unauthenticated challenge for the 3RD API","description":"Returns 401 with a WWW-Authenticate challenge pointing at the OAuth protected-resource metadata for the product MCP.","security":[{"mcpOAuth":["openid","profile","email"]}],"responses":{"401":{"description":"Missing bearer token","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sandbox":{"servers":[{"url":"https://www.get3rd.com"}],"get":{"operationId":"getSandbox","summary":"Describe the free sandbox","description":"Public description of the free sandbox: where to mint a key and which call returns fixture visibility rows. No credentials.","responses":{"200":{"description":"Sandbox description","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Sandbox"}}}},"429":{"description":"Rate limit exceeded","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sandbox/keys":{"servers":[{"url":"https://www.get3rd.com"}],"post":{"operationId":"createSandboxKey","summary":"Mint a free sandbox key","description":"Self-serve key generation. No credentials, no card and no contact form. The key is usable immediately on GET /v1/sandbox/visibility. The example key 3rd_sandbox_public_agent also works.","responses":{"201":{"description":"Sandbox key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxKey"}}}},"429":{"description":"Rate limit exceeded","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/v1/sandbox/visibility":{"servers":[{"url":"https://www.get3rd.com"}],"get":{"operationId":"getSandboxVisibility","summary":"Read fixture visibility","description":"Fixture visibility rows for the fictional sandbox brand. Send a sandbox key in X-API-Key. This is not a customer account.","security":[{"SandboxKey":[]}],"responses":{"200":{"description":"Fixture visibility rows","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SandboxVisibility"}}}},"401":{"description":"Missing or invalid sandbox key","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/ask":{"servers":[{"url":"https://www.get3rd.com"}],"post":{"operationId":"askSite","summary":"Ask the public 3RD site","description":"NLWeb ask. Matches the question against public pages. Send an Idempotency-Key to reuse the response on retry. Does not read customer data.","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Caller-chosen key. A repeat POST with the same key returns the first response."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"object","properties":{"text":{"type":"string"}},"required":["text"]},"prefer":{"type":"object","properties":{"streaming":{"type":"boolean"}}}},"required":["query"]}}}},"responses":{"200":{"description":"NLWeb results, or a text/event-stream when prefer.streaming is true"},"400":{"description":"The query text is missing","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limit exceeded","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/api/export/v1/brands":{"get":{"operationId":"listBrands","summary":"List brands","description":"Every active brand this key can read. An unscoped key returns every active brand in its organization; a key limited to specific brands returns only those. Use a brand's `id` as the `brandId` parameter on the other endpoints. Returns the matching brands in one response — no pagination, no date filter.","tags":["Export"],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/BrandsRow"}}},"required":["data"]}}}},"401":{"description":"Missing, unknown, revoked, expired, or wrongly scoped API key, or one whose creator is no longer an owner or admin of the organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key's organization has no active paid plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"servers":[{"url":"https://app.get3rd.com"}]},"/api/export/v1/visibility":{"get":{"operationId":"getVisibility","summary":"Daily brand visibility","description":"How often the brand appeared in AI answers, one row per date × model × provider × market. Counts the answers the dashboard counts: error answers and answers to retired prompts are left out, and so are branded prompts (prompts that name the brand) unless the brand is set to count them. Visibility rate is `visible_count / total_prompts`, computed per bucket.","tags":["Export"],"parameters":[{"name":"brandId","in":"query","required":true,"schema":{"type":"string","format":"uuid"},"description":"Brand to report on, from `GET /api/export/v1/brands`. A brand outside the key's organization, or outside the brands the key is pinned to, returns 404."},{"name":"fromDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Start of the window, inclusive (`YYYY-MM-DD`). Defaults to 30 days ago. Clamped to the plan's lookback window without an error, so read `meta.fromDate` for the window actually applied."},{"name":"toDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"End of the window, inclusive (`YYYY-MM-DD`). Defaults to now."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous response's `pagination.nextCursor`. Omit for the first page."}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VisibilityRow"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","pagination","meta"]}}}},"400":{"description":"Missing or malformed parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, revoked, expired, or wrongly scoped API key, or one whose creator is no longer an owner or admin of the organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key's organization has no active paid plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Brand this key cannot read — unknown, inactive, in another organization, or outside the key's brand list. Returned instead of 403 so the response does not reveal whether the id exists elsewhere.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"servers":[{"url":"https://app.get3rd.com"}]},"/api/export/v1/citations":{"get":{"operationId":"getCitations","summary":"Citations per URL per day","description":"Which URLs the AI models cited, one row per date × URL, split by owned vs earned. Counts citations in the answers the dashboard counts: error answers and answers to retired prompts are left out. Branded prompts count.","tags":["Export"],"parameters":[{"name":"brandId","in":"query","required":true,"schema":{"type":"string","format":"uuid"},"description":"Brand to report on, from `GET /api/export/v1/brands`. A brand outside the key's organization, or outside the brands the key is pinned to, returns 404."},{"name":"fromDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Start of the window, inclusive (`YYYY-MM-DD`). Defaults to 30 days ago. Clamped to the plan's lookback window without an error, so read `meta.fromDate` for the window actually applied."},{"name":"toDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"End of the window, inclusive (`YYYY-MM-DD`). Defaults to now."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous response's `pagination.nextCursor`. Omit for the first page."}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CitationsRow"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","pagination","meta"]}}}},"400":{"description":"Missing or malformed parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, revoked, expired, or wrongly scoped API key, or one whose creator is no longer an owner or admin of the organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key's organization has no active paid plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Brand this key cannot read — unknown, inactive, in another organization, or outside the key's brand list. Returned instead of 403 so the response does not reveal whether the id exists elsewhere.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"servers":[{"url":"https://app.get3rd.com"}]},"/api/export/v1/competitors":{"get":{"operationId":"getCompetitors","summary":"Daily competitor visibility","description":"How often each tracked competitor appeared in AI answers, one row per date × competitor. Counts the answers the dashboard counts: error answers and answers to retired prompts are left out, and so are branded prompts (prompts that name the brand) unless the brand is set to count them. When branded prompts are excluded (the default), a prompt that names a tracked competitor or one of its aliases is also left out of that competitor's visibility — both the mentions and the total — while it still counts for the brand and for every competitor it does not name, so each competitor has its own denominator (`total_responses`). A competitor counts as mentioned when the answer names it or one of its aliases. The rate is `competitor_visible_responses / total_responses × 100` for that row.","tags":["Export"],"parameters":[{"name":"brandId","in":"query","required":true,"schema":{"type":"string","format":"uuid"},"description":"Brand to report on, from `GET /api/export/v1/brands`. A brand outside the key's organization, or outside the brands the key is pinned to, returns 404."},{"name":"fromDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Start of the window, inclusive (`YYYY-MM-DD`). Defaults to 30 days ago. Clamped to the plan's lookback window without an error, so read `meta.fromDate` for the window actually applied."},{"name":"toDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"End of the window, inclusive (`YYYY-MM-DD`). Defaults to now."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous response's `pagination.nextCursor`. Omit for the first page."}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CompetitorsRow"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","pagination","meta"]}}}},"400":{"description":"Missing or malformed parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, revoked, expired, or wrongly scoped API key, or one whose creator is no longer an owner or admin of the organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key's organization has no active paid plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Brand this key cannot read — unknown, inactive, in another organization, or outside the key's brand list. Returned instead of 403 so the response does not reveal whether the id exists elsewhere.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"servers":[{"url":"https://app.get3rd.com"}]},"/api/export/v1/citation-share":{"get":{"operationId":"getCitationShare","summary":"Citation Share per URL per day","description":"The citations behind the Citation Share metric, one row per date × URL. Counts the citations the Overview Citation Share card counts: error answers, answers to retired prompts and answers to prompts that don't count in metrics are left out; branded prompts count. Citation Share for any window is `sum(owned_citations) / sum(citations) × 100` over that window's rows, so the headline and the URLs behind it come from the same rows. Differs from `/citations` in two ways that keep the sums equal to the card: a citation is dated by the answer that made it rather than by when the citation was recorded, and ownership is counted per citation rather than once per URL and day.","tags":["Export"],"parameters":[{"name":"brandId","in":"query","required":true,"schema":{"type":"string","format":"uuid"},"description":"Brand to report on, from `GET /api/export/v1/brands`. A brand outside the key's organization, or outside the brands the key is pinned to, returns 404."},{"name":"fromDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Start of the window, inclusive (`YYYY-MM-DD`). Defaults to 30 days ago. Clamped to the plan's lookback window without an error, so read `meta.fromDate` for the window actually applied."},{"name":"toDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"End of the window, inclusive (`YYYY-MM-DD`). Defaults to now."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous response's `pagination.nextCursor`. Omit for the first page."}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/CitationShareRow"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","pagination","meta"]}}}},"400":{"description":"Missing or malformed parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, revoked, expired, or wrongly scoped API key, or one whose creator is no longer an owner or admin of the organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key's organization has no active paid plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Brand this key cannot read — unknown, inactive, in another organization, or outside the key's brand list. Returned instead of 403 so the response does not reveal whether the id exists elsewhere.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"servers":[{"url":"https://app.get3rd.com"}]},"/api/export/v1/recommended-rate":{"get":{"operationId":"getRecommendedRate","summary":"Daily Recommended rate","description":"How often AI answers recommend the brand, and each tracked competitor, as the winner. One row per date × entity, the brand first. The same figure as the dashboard's Recommended rate view with no filter set: answers to branded prompts are left out, and only answers already checked for a recommendation count. A day with no checked answers is absent. A rate is computed over prompt groups, so a window's rate is not the average of its daily rates.","tags":["Export"],"parameters":[{"name":"brandId","in":"query","required":true,"schema":{"type":"string","format":"uuid"},"description":"Brand to report on, from `GET /api/export/v1/brands`. A brand outside the key's organization, or outside the brands the key is pinned to, returns 404."},{"name":"fromDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Start of the window, inclusive (`YYYY-MM-DD`). Defaults to 30 days ago. Clamped to the plan's lookback window without an error, so read `meta.fromDate` for the window actually applied."},{"name":"toDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"End of the window, inclusive (`YYYY-MM-DD`). Defaults to now."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous response's `pagination.nextCursor`. Omit for the first page."}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RecommendedRateRow"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","pagination","meta"]}}}},"400":{"description":"Missing or malformed parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, revoked, expired, or wrongly scoped API key, or one whose creator is no longer an owner or admin of the organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key's organization has no active paid plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Brand this key cannot read — unknown, inactive, in another organization, or outside the key's brand list. Returned instead of 403 so the response does not reveal whether the id exists elsewhere.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"servers":[{"url":"https://app.get3rd.com"}]},"/api/export/v1/sentiment":{"get":{"operationId":"getSentiment","summary":"Daily brand sentiment","description":"How AI answers talk about the brand, one row per date: the positive, neutral and negative phrases about the brand, and the sentiment score the Overview Brand Sentiment card shows. All markets. The score is the confidence-weighted share of positive phrases among positive and negative ones; neutral phrases are counted but don't move it. For a window, compute `sum(positive_weight) / (sum(positive_weight) + sum(negative_weight)) × 100` rather than averaging the daily scores. Days with no phrases about the brand are absent.","tags":["Export"],"parameters":[{"name":"brandId","in":"query","required":true,"schema":{"type":"string","format":"uuid"},"description":"Brand to report on, from `GET /api/export/v1/brands`. A brand outside the key's organization, or outside the brands the key is pinned to, returns 404."},{"name":"fromDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"Start of the window, inclusive (`YYYY-MM-DD`). Defaults to 30 days ago. Clamped to the plan's lookback window without an error, so read `meta.fromDate` for the window actually applied."},{"name":"toDate","in":"query","required":false,"schema":{"type":"string","format":"date"},"description":"End of the window, inclusive (`YYYY-MM-DD`). Defaults to now."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque cursor from the previous response's `pagination.nextCursor`. Omit for the first page."}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/SentimentRow"}},"pagination":{"$ref":"#/components/schemas/Pagination"},"meta":{"$ref":"#/components/schemas/Meta"}},"required":["data","pagination","meta"]}}}},"400":{"description":"Missing or malformed parameter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Missing, unknown, revoked, expired, or wrongly scoped API key, or one whose creator is no longer an owner or admin of the organization","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"The key's organization has no active paid plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Brand this key cannot read — unknown, inactive, in another organization, or outside the key's brand list. Returned instead of 403 so the response does not reveal whether the id exists elsewhere.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"servers":[{"url":"https://app.get3rd.com"}]}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Export API key created in the 3RD app under Settings → Looker Studio."},"mcpOAuth":{"type":"oauth2","description":"OAuth 2.0 for the 3RD product MCP. Clients register at https://app.get3rd.com/api/auth/mcp/register.","flows":{"authorizationCode":{"authorizationUrl":"https://app.get3rd.com/api/auth/mcp/authorize","tokenUrl":"https://app.get3rd.com/api/auth/mcp/token","refreshUrl":"https://app.get3rd.com/api/auth/mcp/token","scopes":{"openid":"Identify the 3RD account","profile":"Read the account name","email":"Read the account email","offline_access":"Refresh the access token"}}}},"SandboxKey":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Sandbox key from POST /v1/sandbox/keys, or the example key 3rd_sandbox_public_agent. Unlocks fixture data only."}},"schemas":{"BrandsRow":{"type":"object","properties":{"id":{"type":"string","description":"Brand id (UUID) — pass as `brandId` to the other endpoints"},"name":{"type":"string","description":"Canonical brand name. Stable — consumers of this versioned endpoint key off it"},"displayName":{"type":["string","null"],"description":"Friendly label shown in the app; null when the brand has none set"},"url":{"type":["string","null"],"deprecated":true,"description":"Deprecated: the website as first entered, which can carry a stray path or tracking parameters. Use `siteUrl`"},"siteUrl":{"type":["string","null"],"description":"Brand's website: its primary tracked domain, plus the tracked section when the brand tracks only part of the site. Null when the brand has no tracked domain"},"industry":{"type":["string","null"],"description":"Industry the brand was classified into"},"createdAt":{"type":"string","format":"date-time","description":"When the brand was added, ISO 8601"}},"required":["id","name","createdAt"]},"VisibilityRow":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"Date (UTC)"},"model_id":{"type":["string","null"],"description":"AI model name (e.g. gpt-4o, claude-3-5-sonnet)"},"provider":{"type":"string","description":"AI provider name (e.g. openai, anthropic, google)"},"market_id":{"type":["string","null"],"description":"Market id (UUID); null for responses not bound to a market"},"market":{"type":"string","description":"Market or region the prompt was run in; empty string when unknown"},"total_prompts":{"type":"integer","description":"Total AI responses analyzed for this bucket"},"visible_count":{"type":"integer","description":"Responses in which the brand was visible (mentioned or ranked)"},"visibility_rate":{"type":"number","description":"Brand visibility rate as a percentage (0–100)"}},"required":["date","provider","market","total_prompts","visible_count","visibility_rate"]},"CitationsRow":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"Date the citation was recorded (UTC)"},"url":{"type":"string","description":"Cited URL"},"domain":{"type":["string","null"],"description":"Domain of the cited URL"},"is_owned":{"type":"boolean","description":"True if the cited URL belongs to the brand's own domain"},"is_agency_sponsored_content":{"type":"boolean","description":"Detected paid/sponsored placement. Always false unless the organization has opted into paid-citation detection"},"brand_mentioned":{"type":["boolean","null"],"description":"Whether the brand is mentioned on this page. Null means not established — the page has not been scraped, or it blocks our crawler — which is not the same as false"},"citation_count":{"type":"integer","description":"Number of distinct AI responses that cited this URL on this date"}},"required":["date","url","is_owned","is_agency_sponsored_content","citation_count"]},"CompetitorsRow":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"Date (UTC)"},"competitor_name":{"type":"string","description":"Competitor display name"},"total_responses":{"type":"integer","description":"AI responses in this competitor's denominator for this date. When branded prompts are excluded, prompts that name this competitor or one of its aliases are left out, so two competitors on the same date can have different totals"},"competitor_visible_responses":{"type":"integer","description":"Responses in which this competitor was mentioned"},"competitor_visibility_rate":{"type":"number","description":"Competitor visibility rate as a percentage (0–100)"}},"required":["date","competitor_name","total_responses","competitor_visible_responses","competitor_visibility_rate"]},"CitationShareRow":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"Date of the answer that cited the URL (UTC)"},"url":{"type":"string","description":"Cited URL"},"domain":{"type":["string","null"],"description":"Domain of the cited URL"},"is_owned":{"type":"boolean","description":"True if any citation of this URL on this date was to a domain the brand owns"},"citations":{"type":"integer","description":"Answers on this date that cited this URL"},"owned_citations":{"type":"integer","description":"Of `citations`, those counted as owned. Ownership is stamped per citation, so a URL whose domain became owned during the day can have fewer owned citations than citations"}},"required":["date","url","is_owned","citations","owned_citations"]},"RecommendedRateRow":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"Date (UTC)"},"entity_name":{"type":"string","description":"The brand's display name, or a tracked competitor's"},"is_brand":{"type":"boolean","description":"True on the brand's own row"},"recommended_rate":{"type":"number","description":"Share of the day's checked answers that recommend this entity as the winner, as a percentage (0–100)"},"judged_answers":{"type":"integer","description":"Answers checked for a recommendation that day. The same on every row of a day: competitors are scored on the brand's answers"}},"required":["date","entity_name","is_brand","recommended_rate","judged_answers"]},"SentimentRow":{"type":"object","properties":{"date":{"type":"string","format":"date","description":"Date (UTC)"},"positive_mentions":{"type":"integer","description":"Phrases about the brand classified positive"},"neutral_mentions":{"type":"integer","description":"Phrases about the brand classified neutral"},"negative_mentions":{"type":"integer","description":"Phrases about the brand classified negative"},"positive_weight":{"type":"number","description":"Sum of the classifier's confidence (0–1) over the positive phrases"},"negative_weight":{"type":"number","description":"Sum of the classifier's confidence (0–1) over the negative phrases"},"sentiment_score":{"type":["number","null"],"description":"Positive share for the day as a percentage (0–100): `positive_weight / (positive_weight + negative_weight) × 100`. Null on a day with only neutral phrases"}},"required":["date","positive_mentions","neutral_mentions","negative_mentions","positive_weight","negative_weight"]},"Pagination":{"type":"object","properties":{"pageSize":{"type":"integer","description":"Rows per page. Always 1000."},"hasMore":{"type":"boolean","description":"Whether another page follows."},"nextCursor":{"type":["string","null"],"description":"Pass as `cursor` to fetch the next page. Null on the last page."}},"required":["pageSize","hasMore","nextCursor"]},"Meta":{"type":"object","properties":{"brandId":{"type":"string","format":"uuid"},"fromDate":{"type":"string","format":"date-time","description":"Start of the window actually queried, after the plan clamp was applied."},"toDate":{"type":"string","format":"date-time","description":"End of the window actually queried, inclusive: the last millisecond of the `toDate` day, or the time of the request when `toDate` is omitted."},"plan":{"type":"string","description":"Billing plan the key's organization is on, which sets the lookback window (lite: no access, pro: 90 days, agency: 180 days, enterprise: full history)."}},"required":["brandId","fromDate","toDate","plan"]},"Error":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable failure reason."}},"required":["error"]},"Problem":{"type":"object","properties":{"type":{"type":"string"},"title":{"type":"string"},"status":{"type":"integer"},"detail":{"type":"string"},"code":{"type":"string"}},"required":["status","code","detail"]},"Sandbox":{"type":"object","properties":{"environment":{"type":"string"},"tier":{"type":"string"},"price":{"type":"number"},"keyGeneration":{"type":"string"},"visibility":{"type":"string"}},"required":["environment","tier","price","keyGeneration","visibility"]},"SandboxKey":{"type":"object","properties":{"apiKey":{"type":"string"},"tier":{"type":"string"},"environment":{"type":"string"},"price":{"type":"number"}},"required":["apiKey","tier","environment","price"]},"SandboxVisibility":{"type":"object","properties":{"environment":{"type":"string"},"tier":{"type":"string"},"price":{"type":"number"},"data":{"type":"array","items":{"type":"object"}}},"required":["environment","tier","price","data"]},"Product":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"mcp":{"type":"string"},"openapi":{"type":"string"}},"required":["name","description","mcp","openapi"]}}}}