{"openapi":"3.1.0","info":{"title":"SEOmonitor (BYOK) API","version":"0.1.0","description":"SEOmonitor (BYOK) lets an AI assistant read your own SEOmonitor data through the SEOmonitor API with a key you supply (SEOmonitor API token (sent as the raw Authorization header)). Read-only: 12 tools (list_companies, list_tracked_campaigns, list_keyword_groups, list_tracked_keywords, get_daily_keyword_ranks, get_daily_group_visibility, get_serp_visibility, get_share_of_voice,...\n\nEvery operation is read-only or compute-only. The same tools are available over MCP (streamable HTTP) at https://byok-seomonitor.connectorbay.com/mcp.","contact":{"name":"Unify Dynamics LLC","email":"agent@connectorbay.com","url":"https://connectorbay.com/byok-seomonitor/docs"},"termsOfService":"https://connectorbay.com/byok-seomonitor/terms"},"servers":[{"url":"https://byok-seomonitor.connectorbay.com"}],"externalDocs":{"url":"https://connectorbay.com/byok-seomonitor/docs"},"security":[{"upstreamKey":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"Optional. A Pro API key raises rate limits; no credentials are required."},"upstreamKey":{"type":"apiKey","in":"header","name":"X-Upstream-Key","description":"Your own key for the service this connector wraps (bring your own key). Used for that one call only; never stored, logged or cached."}},"schemas":{"Error":{"type":"object","properties":{"ok":{"const":false},"error":{"type":"object"}}}}},"paths":{"/v1/tools/list_companies":{"post":{"operationId":"list_companies","summary":"List the SEOmonitor companies (accounts) your token can access, with access type and subscription status. Use for \"Which","description":"List the SEOmonitor companies (accounts) your token can access, with access type and subscription status. Use for \"Which SEOmonitor accounts does my token cover\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{},"title":"list_companiesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_tracked_campaigns":{"post":{"operationId":"list_tracked_campaigns","summary":"List active tracked campaigns across your companies with domain, location, keyword count, latest Visibility and health s","description":"List active tracked campaigns across your companies with domain, location, keyword count, latest Visibility and health status. Use for \"Which SEO campaigns am I tracking and how visible are they\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"company_id":{"anyOf":[{"minimum":1,"type":"integer"},{"type":"null"}],"default":null,"description":"Only campaigns of this company id (from list_companies).","title":"Company Id"},"campaign_ids":{"anyOf":[{"maxLength":200,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated campaign ids to return.","title":"Campaign Ids"},"limit":{"anyOf":[{"maximum":100,"minimum":1,"type":"integer"},{"type":"null"}],"default":10,"description":"How many campaigns to return (1 to 100, default 10).","title":"Limit"},"offset":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":0,"description":"Records to skip, for paging.","title":"Offset"}},"title":"list_tracked_campaignsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_keyword_groups":{"post":{"operationId":"list_keyword_groups","summary":"List a campaign's keyword groups, folders and smart groups with their ids, as a nested structure. Use for \"What keyword ","description":"List a campaign's keyword groups, folders and smart groups with their ids, as a nested structure. Use for \"What keyword groups does my SEOmonitor campaign have\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"campaign_id":{"description":"Id of the tracked campaign (campaign_info.id from list_tracked_campaigns).","minimum":1,"title":"Campaign Id","type":"integer"}},"required":["campaign_id"],"title":"list_keyword_groupsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_tracked_keywords":{"post":{"operationId":"list_tracked_keywords","summary":"List a campaign's tracked keywords with search volume, desktop and mobile rank and trend, ranking landing page and oppor","description":"List a campaign's tracked keywords with search volume, desktop and mobile rank and trend, ranking landing page and opportunity score for a date range. Use for \"Which of my tracked keywords rank best in SEOmonitor\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"campaign_id":{"description":"Id of the tracked campaign (campaign_info.id from list_tracked_campaigns).","minimum":1,"title":"Campaign Id","type":"integer"},"start_date":{"description":"First day of the range, YYYY-MM-DD.","maxLength":10,"title":"Start Date","type":"string"},"end_date":{"description":"Last day of the range, YYYY-MM-DD.","maxLength":10,"title":"End Date","type":"string"},"group_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Keyword group id from list_keyword_groups. Special ids: 0 all keywords, -1 brand folder, -2 ungrouped keywords.","title":"Group Id"},"keyword_ids":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated keyword ids to restrict the data to (keyword_id from list_tracked_keywords).","title":"Keyword Ids"},"search":{"anyOf":[{"maxLength":100,"type":"string"},{"type":"null"}],"default":null,"description":"Only keywords containing this text (case-insensitive).","title":"Search"},"order_by":{"anyOf":[{"enum":["keyword","search_volume","year-over-year","rank","rank_trend","rank_trend_impact","opportunity"],"type":"string"},{"type":"null"}],"default":null,"description":"Sort field.","title":"Order By"},"order_direction":{"anyOf":[{"enum":["asc","desc"],"type":"string"},{"type":"null"}],"default":null,"description":"Sort direction, asc when omitted.","title":"Order Direction"},"limit":{"anyOf":[{"maximum":1000,"minimum":1,"type":"integer"},{"type":"null"}],"default":50,"description":"How many records to return (1 to 1000, default 50).","title":"Limit"},"offset":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":0,"description":"Records to skip, for paging.","title":"Offset"}},"required":["campaign_id","start_date","end_date"],"title":"list_tracked_keywordsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_daily_keyword_ranks":{"post":{"operationId":"get_daily_keyword_ranks","summary":"Get daily desktop and mobile ranks of tracked keywords over a date range (one entry per keyword with a rank series). Use","description":"Get daily desktop and mobile ranks of tracked keywords over a date range (one entry per keyword with a rank series). Use for \"How did my keyword ranks move day by day in SEOmonitor\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"campaign_id":{"description":"Id of the tracked campaign (campaign_info.id from list_tracked_campaigns).","minimum":1,"title":"Campaign Id","type":"integer"},"start_date":{"description":"First day of the range, YYYY-MM-DD.","maxLength":10,"title":"Start Date","type":"string"},"end_date":{"description":"Last day of the range, YYYY-MM-DD.","maxLength":10,"title":"End Date","type":"string"},"group_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Keyword group id from list_keyword_groups. Special ids: 0 all keywords, -1 brand folder, -2 ungrouped keywords.","title":"Group Id"},"keyword_ids":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated keyword ids to restrict the data to (keyword_id from list_tracked_keywords).","title":"Keyword Ids"},"search":{"anyOf":[{"maxLength":100,"type":"string"},{"type":"null"}],"default":null,"description":"Only keywords containing this text.","title":"Search"},"limit":{"anyOf":[{"maximum":1000,"minimum":1,"type":"integer"},{"type":"null"}],"default":20,"description":"How many records to return (1 to 1000, default 20).","title":"Limit"},"offset":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":0,"description":"Records to skip, for paging.","title":"Offset"}},"required":["campaign_id","start_date","end_date"],"title":"get_daily_keyword_ranksArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_daily_group_visibility":{"post":{"operationId":"get_daily_group_visibility","summary":"Get the daily Visibility and average weighted rank of the campaign website for a keyword group over a date range. Use fo","description":"Get the daily Visibility and average weighted rank of the campaign website for a keyword group over a date range. Use for \"What is my SEOmonitor Visibility trend this month\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"campaign_id":{"description":"Id of the tracked campaign (campaign_info.id from list_tracked_campaigns).","minimum":1,"title":"Campaign Id","type":"integer"},"start_date":{"description":"First day of the range, YYYY-MM-DD.","maxLength":10,"title":"Start Date","type":"string"},"end_date":{"description":"Last day of the range, YYYY-MM-DD.","maxLength":10,"title":"End Date","type":"string"},"group_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Keyword group id from list_keyword_groups. Special ids: 0 all keywords, -1 brand folder, -2 ungrouped keywords.","title":"Group Id"},"keyword_ids":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated keyword ids to restrict the data to (keyword_id from list_tracked_keywords).","title":"Keyword Ids"},"domain":{"anyOf":[{"maxLength":100,"type":"string"},{"type":"null"}],"default":null,"description":"Competitor domain to report instead of the campaign website.","title":"Domain"}},"required":["campaign_id","start_date","end_date"],"title":"get_daily_group_visibilityArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_serp_visibility":{"post":{"operationId":"get_serp_visibility","summary":"Get daily SERP Visibility split into traditional visibility, SERP feature impact and CTR for a campaign. Use for \"How mu","description":"Get daily SERP Visibility split into traditional visibility, SERP feature impact and CTR for a campaign. Use for \"How much do SERP features affect my SEOmonitor visibility\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"campaign_id":{"description":"Id of the tracked campaign (campaign_info.id from list_tracked_campaigns).","minimum":1,"title":"Campaign Id","type":"integer"},"start_date":{"description":"First day of the range, YYYY-MM-DD.","maxLength":10,"title":"Start Date","type":"string"},"end_date":{"description":"Last day of the range, YYYY-MM-DD.","maxLength":10,"title":"End Date","type":"string"},"group_id":{"anyOf":[{"maxLength":10,"type":"string"},{"type":"null"}],"default":"0","description":"Keyword group id, 0 for all keywords or 'brand' for brand keywords.","title":"Group Id"},"device":{"anyOf":[{"enum":[1,2],"type":"integer"},{"type":"null"}],"default":1,"description":"Device: 1 desktop or 2 mobile.","title":"Device"}},"required":["campaign_id","start_date","end_date"],"title":"get_serp_visibilityArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_share_of_voice":{"post":{"operationId":"get_share_of_voice","summary":"Get Share of Voice on one date: organic, Google AI Overview and AI Search shares for the campaign website and competitor","description":"Get Share of Voice on one date: organic, Google AI Overview and AI Search shares for the campaign website and competitors. Use for \"Who has the biggest share of voice for my keywords in SEOmonitor\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"campaign_id":{"description":"Id of the tracked campaign (campaign_info.id from list_tracked_campaigns).","minimum":1,"title":"Campaign Id","type":"integer"},"date":{"description":"Day to report, YYYY-MM-DD.","maxLength":10,"title":"Date","type":"string"},"group_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Keyword group id from list_keyword_groups. Special ids: 0 all keywords, -1 brand folder, -2 ungrouped keywords.","title":"Group Id"},"keyword_ids":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated keyword ids to restrict the data to (keyword_id from list_tracked_keywords).","title":"Keyword Ids"},"competitors":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated competitor domains.","title":"Competitors"},"device":{"anyOf":[{"enum":["d","m","desktop","mobile"],"type":"string"},{"type":"null"}],"default":null,"description":"Device: desktop (d) or mobile (m). Desktop when omitted.","title":"Device"}},"required":["campaign_id","date"],"title":"get_share_of_voiceArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_daily_share_of_clicks":{"post":{"operationId":"get_daily_share_of_clicks","summary":"Get the daily share of clicks of the campaign domain and the top ten domains by visibility for a keyword list. Use for \"","description":"Get the daily share of clicks of the campaign domain and the top ten domains by visibility for a keyword list. Use for \"What is my share of clicks in SEOmonitor\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"campaign_id":{"description":"Id of the tracked campaign (campaign_info.id from list_tracked_campaigns).","minimum":1,"title":"Campaign Id","type":"integer"},"start_date":{"anyOf":[{"maxLength":10,"type":"string"},{"type":"null"}],"default":null,"description":"First day of the range, YYYY-MM-DD.","title":"Start Date"},"end_date":{"anyOf":[{"maxLength":10,"type":"string"},{"type":"null"}],"default":null,"description":"Last day of the range, YYYY-MM-DD.","title":"End Date"},"group_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Keyword group id from list_keyword_groups. Special ids: 0 all keywords, -1 brand folder, -2 ungrouped keywords.","title":"Group Id"},"keyword_ids":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated keyword ids to restrict the data to (keyword_id from list_tracked_keywords).","title":"Keyword Ids"},"device":{"anyOf":[{"enum":["d","m","desktop","mobile"],"type":"string"},{"type":"null"}],"default":null,"description":"Device: desktop (d) or mobile (m). Desktop when omitted.","title":"Device"}},"required":["campaign_id"],"title":"get_daily_share_of_clicksArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_daily_organic_traffic":{"post":{"operationId":"get_daily_organic_traffic","summary":"Get daily organic sessions, ecommerce and goal results and bounce rate for a traffic segment (all, brand, non-brand or a","description":"Get daily organic sessions, ecommerce and goal results and bounce rate for a traffic segment (all, brand, non-brand or a custom segment). Use for \"How many organic sessions did my site get each day per SEOmonitor\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"campaign_id":{"description":"Id of the tracked campaign (campaign_info.id from list_tracked_campaigns).","minimum":1,"title":"Campaign Id","type":"integer"},"start_date":{"description":"First day of the range, YYYY-MM-DD.","maxLength":10,"title":"Start Date","type":"string"},"end_date":{"description":"Last day of the range, YYYY-MM-DD.","maxLength":10,"title":"End Date","type":"string"},"segment":{"anyOf":[{"maxLength":60,"type":"string"},{"type":"null"}],"default":"non-brand","description":"Segment name: all, non-brand (default), brand, or a custom segment name.","title":"Segment"}},"required":["campaign_id","start_date","end_date"],"title":"get_daily_organic_trafficArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/list_ranking_pages":{"post":{"operationId":"list_ranking_pages","summary":"List the landing pages that rank for a campaign's keywords with title, description and the keywords each ranks for. Use ","description":"List the landing pages that rank for a campaign's keywords with title, description and the keywords each ranks for. Use for \"Which of my pages rank for tracked keywords in SEOmonitor\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"campaign_id":{"description":"Id of the tracked campaign (campaign_info.id from list_tracked_campaigns).","minimum":1,"title":"Campaign Id","type":"integer"},"group_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Keyword group id from list_keyword_groups. Special ids: 0 all keywords, -1 brand folder, -2 ungrouped keywords.","title":"Group Id"},"search":{"anyOf":[{"maxLength":100,"type":"string"},{"type":"null"}],"default":null,"description":"Only pages whose URL or path contains this text.","title":"Search"},"limit":{"anyOf":[{"maximum":1000,"minimum":1,"type":"integer"},{"type":"null"}],"default":50,"description":"How many records to return (1 to 1000, default 50).","title":"Limit"},"offset":{"anyOf":[{"minimum":0,"type":"integer"},{"type":"null"}],"default":0,"description":"Records to skip, for paging.","title":"Offset"}},"required":["campaign_id"],"title":"list_ranking_pagesArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}},"/v1/tools/get_ai_search_stats":{"post":{"operationId":"get_ai_search_stats","summary":"Get AI Search presence, citation and sentiment stats per engine (ChatGPT, Gemini, Perplexity) for a campaign and date ra","description":"Get AI Search presence, citation and sentiment stats per engine (ChatGPT, Gemini, Perplexity) for a campaign and date range. Use for \"Is my brand cited by AI search engines according to SEOmonitor\".","tags":["tools"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"properties":{"campaign_id":{"description":"Id of the tracked campaign (campaign_info.id from list_tracked_campaigns).","minimum":1,"title":"Campaign Id","type":"integer"},"start_date":{"description":"First day of the range, YYYY-MM-DD.","maxLength":10,"title":"Start Date","type":"string"},"end_date":{"description":"Last day of the range, YYYY-MM-DD.","maxLength":10,"title":"End Date","type":"string"},"group_id":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Keyword group id from list_keyword_groups. Special ids: 0 all keywords, -1 brand folder, -2 ungrouped keywords.","title":"Group Id"},"keyword_ids":{"anyOf":[{"maxLength":300,"type":"string"},{"type":"null"}],"default":null,"description":"Comma-separated keyword ids to restrict the data to (keyword_id from list_tracked_keywords).","title":"Keyword Ids"},"gpt_provider":{"anyOf":[{"enum":["openai","gemini","perplexity"],"type":"string"},{"type":"null"}],"default":null,"description":"Only this engine.","title":"Gpt Provider"}},"required":["campaign_id","start_date","end_date"],"title":"get_ai_search_statsArguments","type":"object"}}}},"responses":{"200":{"description":"Tool result. `ok: true` on success; `ok: false` with a structured `error` (provider_unavailable, upstream_error, bad_input) when the tool could not answer.","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"422":{"description":"Arguments failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limit exceeded (see Retry-After)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}},"x-read-only":true}}}}