{"title":"Supermetrics MCP Changelog","format":"markdown","content":"# Changelog\n\nAll notable changes to the Supermetrics MCP server will be documented in this file.\n\n<!-- next-release -->\n\n## [1.27.52] - 2026-11-12\n\n### Added\n\n- **Facebook Ads creatives can now carry Meta's Advantage+ Creative feature settings.**\n  Set `degrees_of_freedom_spec` on an ad creative with each feature's `enroll_status` (`OPT_IN` or `OPT_OUT`). A named feature replaces its whole stored entry, including customizations; omitted features retain their settings. Confirm the stored setting by reading the campaign with `campaign_and_resource_get`.\n\n  Campaign `failures[]` entries now declare `kind` and `reason`, distinguishing `outcome_unknown` from discarded, refused, or not-applied changes so callers can reconcile before retrying. Misplaced `degrees_of_freedom_spec` values now fail before the campaign write with guidance to place them under `ad_groups[].ads[].creative`.\n\n## [1.27.51] - 2026-11-12\n\n### Changed\n\n- Instagram connections made through the MCP server now ask for comment and publishing permissions up front, so commenting and publishing work without reconnecting Instagram later.\n- The creative picker no longer needs an account ID for uploads and AI image generation; an account is needed only to show the platform's asset library. When the account is not on the chosen platform, the picker still opens for uploads and AI images and says why the library is missing.\n- When a post no longer exists, `manage_social_media` now says so and tells the assistant not to retry it, so scheduled agents that check a list of posts stop retrying deleted ones.\n- `manage_social_media` corrects more calls instead of refusing them: a comment sent with both a post and a comment id is posted as a reply, an unsupported `title` is dropped with a note, frame-sequence options on a single post are ignored, and a LinkedIn TEXT post with a `link_url` is published as a LINK post. Listing scheduled posts without a platform no longer adds a note about platforms you have not connected.\n\n## [1.27.49] - 2026-11-12\n\n### Added\n\n- `manage_social_media` can now check a comment, a reply, hiding or deleting a comment, and turning a post's comments on or off with `validate_only`, without changing anything.\n\n## [1.27.48] - 2026-11-12\n\n### Added\n\n- **Campaign management can request per-ad Advantage+ music control for Meta ads.** Set `creative.advantage_plus_music` to false to request no automatic music, or true to request Meta's random music. If a read omits audio state, that state is unknown, not proof of an opt-out. Re-send an explicit choice when a later creative edit cannot be verified from a read.\n\n## [1.27.45] - 2026-11-11\n\n### Changed\n\n- Platform tool descriptions, server instructions and approval messages now state what each tool does and returns, name only tools available on the Platform connection, and describe approval links plainly.\n\n### Fixed\n\n- `list_transfers` now hides secret data source setting values, such as passwords, key files and other free-text values, as `[redacted: write-only]`. Sending that value back in a `manage_transfer` update keeps the stored value; it is refused where there is no stored value. When other settings of the same connection change in that update, the approval summary and the `validate_update` notes warn that the stored value will be used with the new values.\n\n## [1.27.42] - 2026-11-11\n\n### Added\n\n- Two new skills through MCP skill discovery: `supermetrics-social-media-publishing` (posting, scheduling, comments and reviews on Instagram, LinkedIn pages and Google Business Profile, with approval and a dry run before every post) and `supermetrics-audits-and-monitors` (Google Ads and Meta Ads account audits, and scheduled metric, landing-page and naming-convention monitors).\n\n### Fixed\n\n- **Campaign approval refusals are no longer reported as platform rejections.** Changes blocked because the approved connection or campaign changed, or because the approval belongs to another user or team, now use a blocked outcome and explain what to review next.\n\n## [1.27.40] - 2026-11-10\n\n### Fixed\n\n- **Approval links: a short outage of the approval store no longer breaks links or calls them expired.** When the\n  store cannot be written, `manage_campaign` and `manage_social_media` now fail and ask to send the same request again\n  (or, after a social job status check, to check the job again) instead of returning an approval link that only one\n  server could open. When it cannot be read, the approval page says approvals are temporarily unavailable and to reload\n  in a minute, instead of \"Unknown or expired token\", and Approve answers the same; the link keeps working afterwards.\n\n## [1.27.37] - 2026-11-10\n\n### Fixed\n\n- **Approval links: a link that was already approved no longer reads as expired a day later.** The outcome of an\n  approval is now kept for 7 days instead of 24 hours, so reopening a used link shows \"This change was already approved\n  and applied\" (or how it ended), and `approval_status` keeps answering with the outcome. An expired link the page knows\n  nothing about now says the change may already be applied (for an invitation: may already have been sent), instead of\n  \"Unknown or expired token\". A link that stopped working before its expiry time, with no record of use, asks for a\n  fresh link instead.\n\n## [1.27.36] - 2026-11-10\n\n### Fixed\n\n- Campaign management: the `extensions.locations` description for Google Ads now says that locations are not linked to a campaign and are never returned on read, because Google Ads gives campaigns the location assets of their account, or of a location group set on the campaign in Google Ads. It used to suggest they could be linked, but every link was refused.\n\n## [1.27.35] - 2026-11-10\n\n### Changed\n\n- Platform list reads (logins, login links, blends, accounts in an account tag, transfers, destinations, table schemas, incomplete backfills and team members) now return one page at a time, with `total` and `next_offset` to fetch the next page. These lists now come in a fixed order: newest or highest id first, team members by user id, and tag accounts by data source, username and account. An offset past the end of a list returns a note that says so, with the list total. An out-of-range `limit` on `list_logins` and `list_transfers`, whose range depends on the action, and on `list_backfills` now gets an error that names the action and its range. Notes on compressed Platform results now come in the result's `notes` field instead of inside the text. Backfill results, including the results of an approved backfill create or cancel, now show at most 10 errors per backfill (1 per row in `list_incomplete`), together with the full `errors_count` and `truncated` when errors were cut.\n\n## [1.27.34] - 2026-11-10\n\n### Added\n\n- **TikTok app campaigns: the campaign schema now lists the keys they need on create.**\n  `manage_campaign` shows `app_promotion_type`, `campaign_type` (REGULAR_CAMPAIGN) and `app_id` on the campaign and `app_id` on the ad group for TikTok APP_PROMOTION, all create only.\n\n### Changed\n\n- Skills served through MCP skill discovery now carry the `supermetrics-` brand prefix (for example `supermetrics-campaign-management`), with clearer descriptions that list example requests and point to the right skill for nearby ones.\n\n### Fixed\n\n- Changing the approval level from the approval page after approving a change works again; saving had always failed with an error.\n\n## [1.27.33] - 2026-11-10\n\n### Fixed\n\n- When an approval fails because the chat's Supermetrics sign-in changed after the AI made the request, the approval page now says so, instead of asking you to reconnect a data source that is fine.\n\n## [1.27.32] - 2026-11-10\n\n### Added\n\n- The approval page shows the data source's logo, and after an approved change is applied, the account's connection owner can change how often AI changes need their approval, right on the page.\n\n## [1.27.31] - 2026-11-10\n\n### Changed\n\n- On `/platform`, `manage_login_link`, `manage_destination`, `manage_backfill`, `manage_table_schema` and `manage_transfer` now run only their write actions: a read action sent to one fails with an error naming the `list_*` tool that runs it. `validate` and `validate_update` moved from `manage_transfer` to `list_transfers`, since they check a transfer configuration without saving it.\n\n## [1.27.30] - 2026-11-10\n\n### Fixed\n\n- **Approval links: a link that was changed on the way now says how to get it again.** When a chat assistant retypes\n  the approval link and changes or drops characters, the approval page no longer shows \"Invalid signature\" or a generic\n  \"invalid link\". It says the link is incomplete or does not match the one Supermetrics created, that nothing was\n  applied, and to ask in the chat for the link again, unchanged. A bad signature answer carries `link_changed: true`.\n  The approval result now also asks the assistant to show the link exactly as given.\n\n## [1.27.29] - 2026-11-10\n\n### Fixed\n\n- **manage_activation_query: readiness notices are declared for the agent to show.** Notices on readiness gaps, like Google Ads terms acceptance, are now part of the documented response, and the agent is told to show the Google Ads consent notice verbatim and ask before setting terms acceptance or consent.\n\n## [1.27.28] - 2026-11-10\n\n### Changed\n\n- **Campaign writes: a clear note when Meta says the app cannot make an ad set call.** The note says Meta does not name the field, that it may be the targeting the update sends back, and to send the change without targeting fields or make it in Meta Ads Manager instead of resending it unchanged.\n- **Campaign writes: clearer wording when Meta refuses a change as a permission problem.** The note now says the Page, Instagram account, WhatsApp number or ad account may not be visible to the Facebook user behind the connection, or that the action may be limited to some account types, and points to that user's access in Meta Business Settings.\n- **Campaign writes: the assistant now stops retrying after a Meta security check.** The note tells the user what the Facebook user must do and tells the assistant not to write to that ad account again until the user confirms the check is done and the account is reconnected.\n- **Campaign writes: the existing-post field now warns about messaging ad sets.** With more than one messaging app an existing post is refused; with one (WhatsApp, Messenger, Instagram Direct) Meta may refuse it. A single image or video is the safer choice.\n\n## [1.27.27] - 2026-11-10\n\n### Added\n\n- **Meta Ads: show a different image or video per placement in one ad.** `manage_campaign` accepts\n  `creative.placement_assets`, which can use creatives uploaded in the creative picker (`upload_ref`), and the picker\n  now suggests it when you select several creatives for a Meta ad.\n\n### Changed\n\n- **Meta Ads: several `assets` on one ad now need `is_dynamic_creative: true` on the ad set.** Without it the ad is\n  refused instead of being turned into a Dynamic Creative ad. For a different image or video per placement without\n  Dynamic Creative, use `placement_assets`.\n- **manage_campaign: a too-low TikTok budget refusal no longer points the agent at the capability guide.** The refusal message already gives the minimum budget in the account currency, so the guide note is left out when every refusal is a too-low budget. This holds for a direct write and for an approval read back with approval_status, whether the platform refusal comes as a failed result or as an error. The error form needs a SuperAPI that sends `error.failure_reasons` and `additional_reasons`; with an older SuperAPI the note is added as before. Any other refusal in the same write keeps the note.\n\n## [1.27.26] - 2026-11-10\n\n### Added\n\n- When AI changes are off for an Instagram, LinkedIn page or Google Business Profile account, a social media write by the account's connection owner now returns an approval link instead of an error. Approving allows AI changes for the account and applies the write in one click.\n\n## [1.27.25] - 2026-11-10\n\n### Changed\n\n- **Meta Ads: a write refused because of the ad account's status now says so.** The note and the approval page say that Meta does not allow writes on the ad account in its current status, that an admin of the ad account must fix it in Meta Ads Manager, and not to resend before that. Before, this refusal had no specific guidance.\n\n## [1.27.23] - 2026-11-09\n\n### Changed\n\n- Approval pages say AI changes are off for the account, rather than write access, and the button reads \"Allow AI changes and create\" / \"Allow AI changes and apply\". The approval level and how to change it stay in the page's expandable explanation.\n\n## [1.27.21] - 2026-11-09\n\n### Added\n\n- **manage_campaign: Google Ads keywords can be paused and enabled.** A keyword in an ad group's `targeting.keywords` takes `status` (`ENABLED` or `PAUSED`). `targeting.keywords` replaces the ad group's whole keyword set, so send every keyword and set `status` on the ones to change; they are changed in place, and a keyword sent without a status keeps the status it has.\n\n## [1.27.20] - 2026-11-09\n\n### Added\n\n- **BigQuery (BQ3): the data source config now says how to write the SQL.**\n  `data_source_discovery` for `BQ3` adds a note: put the query in `settings.query` with `report_type` `SQL Query`, use `@start_date` and `@end_date` (a date range is always required), pass the numeric project number from `accounts_discovery` as `ds_accounts`, qualify tables in backticks, and expect SELECT only, 1 GiB billed and 200000 rows.\n\n### Changed\n\n- Audit findings are now judged against saved business context, and the assistant says which saved rules it is applying.\n\n### Fixed\n\n- **Dashboard upload lint: BigQuery (BQ3) boards no longer get a false `requested_field_ids` warning.**\n  `manage_dashboards` upload now skips that advisory for boards whose `data_query` calls all use `ds_id` BQ3, because BQ3 results have no field ids (the SQL aliases in row 0 are the columns). Boards that also query another source, and legacy EXT_BQ boards, behave as before.\n\n## [1.27.19] - 2026-11-09\n\n### Added\n\n- Creating a campaign on an ad account without write access no longer fails for the person who connected the account. They get an approval link instead: approving turns on write access (approval level \"All live changes\") and creates the campaign, paused. The page says so before the click. Everyone else still gets the write access error.\n- When approving a change also turns on write access, the approval page now shows the team name and ID, so you can check you are approving in the right team.\n\n## [1.27.18] - 2026-11-09\n\n### Changed\n\n- **Campaign changes on Meta: clearer guidance when Meta refuses a change.** When the Facebook user behind the connection lacks the Advertiser role on the ad account or on the Page, when Meta reports a permission problem, or when an existing post is used on an ad set that sends people to more than one messaging app, the AI and the approval page now say what to fix before trying again. The security check message names the Facebook user the change ran as when known, says only that user sees the check, and points to Meta's review form when reconnecting does not help.\n- `campaign_and_resource_get` no longer fails a read when `campaign_detail_level` is not one of `campaign`, `ad_group` or `full`. A word about keywords, targeting, audiences, budgets or settings now returns the `ad_group` level (or `full` when it also asks for ads or creatives), any other unknown word returns `full`, and a note in the response says which level was returned. A `campaign_detail_level` sent with a resource type other than `campaigns` (for example `history` or `recommendations`) is now ignored with a note instead of failing the read.\n\n## [1.27.17] - 2026-11-09\n\n### Changed\n\n- **manage_campaign: Facebook Ads reads show which post a boosted-post ad promotes.** The `object_story_id` description now says Facebook Ads campaign reads return it, so a read can confirm that an ad boosts the post it was asked to.\n\n## [1.27.16] - 2026-11-09\n\n### Added\n\n- `list_table_schemas` and `manage_table_schema` platform tools for managing Data Warehouse table schemas (table groups)\n\n## [1.27.15] - 2026-11-09\n\n### Changed\n\n- **manage_campaign: each platform's write rules are now in its `supermetrics_guide` capability mode.** When the ad\n  platform or Supermetrics refuses a campaign write, or part of it, on its input (directly or after approval), the\n  result ends with a note naming that platform's mode.\n- Supermetrics Studio now lists connectors that are available for AI chats, not only connectors available for the API.\n\n## [1.27.14] - 2026-11-09\n\n### Fixed\n\n- **manage_social_media: a LinkedIn or Google Business Profile refusal no longer asks you to reconnect.** Invalid input, a page or location the connected account can't manage, a missing item, rate limiting and platform outages now show the platform's reason, even when that reason mentions access being denied.\n\n## [1.27.13] - 2026-11-09\n\n### Fixed\n\n- `accounts_discovery` no longer says a data source has no connections in your team when a connection\n  exists but exposes no accounts. It now names the connected login and explains the likely causes — the\n  login lacks access to the accounts on the provider's side, or the account was created too recently to\n  have appeared yet (which can take up to ~24h) — while still offering the connect link in case the\n  accounts belong to another login or the connection has expired.\n\n## [1.27.12] - 2026-11-07\n\n### Changed\n\n- AI chats are no longer told to share the feature wishlist link whenever a user mentions an idea; the contact tool still points feature requests there.\n\n### Fixed\n\n- manage_audits_and_monitors no longer marks the monitor config label with the \"readOnly\" schema keyword, which Gemini-based clients reject; the description still says it is read-only.\n\n## [1.27.11] - 2026-11-06\n\n### Changed\n\n- Inviting a team member with `manage_user_and_team` now needs your approval: the tool first checks that you can invite someone with that role (team owners and admins can; admins cannot invite owners), then returns a link to a page showing the email, role and team, and the invitation is sent only after you click Approve. If your sign-in has expired or moved to another team by then, or Supermetrics refuses the invitation, nothing is sent and the page says why.\n- Tool inputs that used to accept a free-form object (campaign and ad group settings, creative picker and resource options, monitor configs, dashboard patches, Instagram publishing options) now list their exact keys, and query settings now document `report_type`, so assistants fill them in correctly more often. Inputs that worked before still work.\n- manage_social_media reads ds_id \"LI\" as the LinkedIn page (LIP), as it already read \"IG\" as Instagram (IGI).\n\n## [1.27.10] - 2026-11-06\n\n### Changed\n\n- When Meta refuses a campaign change because of a security check on the Facebook user behind the connection, the result now explains how to clear it (complete the check in Ads Manager, reconnect the account) and not to resend before that. A campaign create that was only partly applied says to re-read the campaign and submit only what is missing. When Meta refuses an ad set for missing EU transparency fields, the result now says to add dsa_beneficiary and dsa_payor to the ad set platform_settings, and the campaign tool guidance states the same.\n\n## [1.27.8] - 2026-11-06\n\n### Added\n\n- **Meta campaigns: ad set bids and spend limits take the account currency.** In `manage_campaign`, send `bid_price`, `daily_spend_max`, `lifetime_spend_max`, `daily_spend_min` and `lifetime_spend_min` in the ad group's `platform_settings` as the amount you mean (2.50 = 2.50), the same unit as `budget_amount` and the other ad platforms. The older `bid_amount`, `daily_spend_cap`, `lifetime_spend_cap`, `daily_min_spend_target` and `lifetime_min_spend_target` still work in Meta's minor units (250 = 2.50). Reads return both forms, and a bid or spend limit Meta did not keep on a new ad set is now reported as a failure.\n\n### Changed\n\n- **AI images are shown for review before they are used.** The assistant now generates AI images for campaigns and social posts in the creative picker so you can check or regenerate them first. It skips that step only when you explicitly say you don't need to review them.\n- **Google Business Profile account lists show only single locations, and data_query takes ALL_ACCOUNTS.** accounts_discovery for GMB no longer lists \"All locations of …\" entries, which can't take posts or review replies. To query every account of the connected logins on any data source with an account list, pass `ds_accounts` ALL_ACCOUNTS.\n\n## [1.27.7] - 2026-11-06\n\n### Changed\n\n- **Meta ads: the tool now explains which text goes where.** The description text is the ad's primary text, the headline is the title, and the link description is the line under the headline. For WhatsApp ads it also names `creative.whatsapp_number`, the number the WhatsApp button opens.\n\n## [1.27.6] - 2026-11-06\n\n### Changed\n\n- **TikTok campaign tools: the parameter descriptions now state the minimum daily budget, the billing and frequency rules for ad groups, and that CUSTOMIZED_USER identities are refused.**\n  The model sees the minimum daily budget (it depends on the account currency, and a LIFETIME budget needs about that much per day), that FOLLOWERS is an accepted optimization goal and uses OCPM billing, that a REACH ad group needs frequency, and that TikTok ads cannot use custom identities.\n\n## [1.27.5] - 2026-11-06\n\n### Added\n\n- **Platform MCP explains a missing subscription.** Rolling out team by team: a Platform MCP tool call on a team whose subscription lacks AI Chats or Platform API access is refused with a message that names what is missing and how to fix it. Connecting and listing tools still work, as does `get_team_info`.\n\n## [1.27.4] - 2026-11-06\n\n### Added\n\n- **manage_social_media: Google Business Profile (ds_id GMB).** Publish text or single-image posts (standard, event or\n  offer, with an optional call-to-action button) to a business location, schedule them, list the location's reviews\n  with `list_comments` (no `media_id`), and reply to or remove a reply to a review.\n\n## [1.27.2] - 2026-11-06\n\n### Added\n\n- New `revoke_login` tool on `/platform` to disconnect a data-source login, with human approval required before the revoke takes effect.\n\n### Changed\n\n- **accounts_discovery: says why the last connect attempt failed.** When a data source has no connections and the user tried to connect it in the last hour, the response now includes the reason and fix from that attempt (for example, a LinkedIn login that isn't a Super admin of any company page), not just a new connect link.\n\n## [1.27.1] - 2026-11-05\n\n### Changed\n\n- **manage_campaign: guidance for Meta ad sets that send people to more than one messaging app.** The parameter descriptions now say these ad sets take a single image, a single video or an existing post with one headline and one primary text, and that call_to_action picks which messaging app the button opens, also for an existing post.\n\n## [1.27.0] - 2026-11-05\n\n### Added\n\n- **Audits and monitors (beta) are open to everyone.** `manage_audits_and_monitors` runs a one-off audit of one Google Ads or Facebook Ads account over the last 7 to 90 days and groups the findings, most severe first, under tracking trust, delivery, waste, efficiency, allocation, change and upside; `read_audits_and_monitors` returns the report. The same tools create, update and run monitors that check metrics, landing pages and naming conventions on Google Ads, Facebook Ads or Google Analytics 4 on a schedule and notify you by email or Slack. Both tools are also in the OpenAPI and Swagger specs for HTTP clients.\n- **Google Ads campaigns: location exclusions.** `manage_campaign` documents `targeting.excluded_locations` (countries) and `targeting.excluded_location_details` (other places, as `{type: geo_target, key: <geo target id>}`), which Meta campaigns already accepted. Google Ads campaign reads return the excluded locations, and creates and updates write them. On a Google Ads update, sending only one of the two fields replaces just the exclusions it lists, and sending both as `[]` clears them. Google Ads cannot exclude a radius, a place that is also targeted stays targeted, and Demand Gen campaigns don't take exclusions. Geo IDs sent as numbers are accepted. A Google Ads forecast does not apply exclusions and now says so in its result.\n\n## [1.26.38] - 2026-11-05\n\n### Fixed\n\n- **Google Ads: turning AI Max off on a Search campaign works.** In an update with no other changes (only `final_url_expansion` and `campaign_type` may come with it), `platform_settings.ai_max_enabled: false` now also turns off text customization and final URL expansion, which Google Ads requires, and the notes say which were turned off. Before, Google refused the change while either was on. Sent with other changes, `ai_max_enabled: false` is not applied (text customization cannot be turned back on through the API): the rest of the update is, and the notes say to send it on its own.\n\n## [1.26.37] - 2026-11-05\n\n### Changed\n\n- **Meta (Facebook Ads): the creative field `link_descriptions` is now documented in `manage_campaign`.** The model now sends the link description under its own name.\n\n## [1.26.35] - 2026-11-05\n\n### Changed\n\n- **Meta ads: a read `tracking_specs` can be sent back.** `manage_campaign` now accepts an ad's `platform_settings.tracking_specs` exactly as a campaign read returned it, which replaces the earlier advice to send it only to change tracking and never copy it to a new ad. Sent back unchanged on update, it writes nothing. On create, specs that name a post other than the one the new ad boosts are left out, the response notes name those posts, and the other specs are still written. An empty list still cannot clear tracking.\n\n## [1.26.33] - 2026-11-04\n\n### Added\n\n- **Meta campaigns: ad set budget sharing.** `manage_campaign` documents `platform_settings.is_adset_budget_sharing_enabled` for Meta campaigns with ad set budgets. `true` lets Meta move up to 20% of an ad set's daily budget to the others and keeps a single campaign bid strategy (with none sent or set, the one the new ad groups all name): an ad set bid strategy that differs is refused, as is `true` with a campaign budget or with `campaign_budget_optimization` `true`. An update that sets `false` gives a `bid_strategy` sent with it to the new ad sets instead of the campaign. New campaigns default to `false`. An update that turns `campaign_budget_optimization` off sets it to `true` unless `false` is sent. Lifetime ad sets with different schedules need `false`. A campaign read returns the value in `platform_details`, and sending it back unchanged writes nothing.\n\n## [1.26.32] - 2026-11-04\n\n### Changed\n\n- **`data_query` now passes `report_type` on for data sources that pick the report from the requested fields.** Most of these data sources use it when it fits the fields; some treat it as a strict choice and refuse a report type that does not fit. When the requested report type did not run because it does not fit the requested fields, the result says which one ran, so you can change the fields and query again.\n\n## [1.26.31] - 2026-11-04\n\n### Changed\n\n- **Meta video ads keep their name.** `manage_campaign` documents `creative.video_title` for Meta videos: an uploaded video is named after it, or after its file when it is left out. A link with no file name, such as a Google Drive download link, needs `video_title`, or the video is named \"Ad Video\". A campaign read now returns a single-video ad's video as `asset_id` with `asset_type` `video` and, when readable, its name in `video_title`. To replace the video, send a new `asset_url`: it wins over `asset_id`.\n\n## [1.26.30] - 2026-11-04\n\n### Added\n\n- **Meta ads: pixel tracking.** `manage_campaign` documents an ad's `platform_settings.tracking_specs` (Meta's list) and a `pixel_id` shortcut that tracks one pixel on the ad. A campaign read returns each Meta ad's `tracking_specs` in the same place. Send them only to change tracking, and don't copy them to a new ad; an empty list cannot clear them.\n\n## [1.26.29] - 2026-11-04\n\n### Added\n\n- **Audience activations: BigQuery sources can now name their date column.** `manage_activation_query` accepts connector settings on the source (for example `settings={\"date_column\": \"created_at\"}`), so a BigQuery activation can filter on a date range. Errors for a missing date range or date column now point to the right source fields.\n\n## [1.26.28] - 2026-11-04\n\n### Changed\n\n- **Meta ad sets: settings are read back where you write them.** `manage_campaign` documents that a campaign read returns each Meta ad set's `optimization_goal`, `billing_event`, `destination_type`, `promoted_object`, `bid_strategy`, `bid_amount` (minor units) and `is_dynamic_creative` in its `platform_settings`, using the keys and units writes take. On update, send only the keys you change: `promoted_object` cannot change on an existing ad set. A bid or Dynamic Creative change that Meta did not keep is reported as a failure.\n\n## [1.26.27] - 2026-11-04\n\n### Removed\n\n- Removed the `migrate-data-studio-to-sm-studio` prompt. Data Studio migration is becoming a tool that works in every client, not only those that show prompts, and is being turned on for teams gradually.\n\n## [1.26.26] - 2026-11-03\n\n### Changed\n\n- **Studio dashboards: Refresh can update a board without reloading it.** The `manage_dashboards`\n  guidance now tells boards to register their data loader with `smOnRefresh`, so Studio's Refresh\n  button re-runs the queries in place (optionally only selected query keys).\n\n## [1.26.25] - 2026-11-03\n\n### Changed\n\n- **On TikTok, campaign updates now list the ad groups and ads they removed.** The result lists `removed_ad_group_ids` and `removed_ad_ids` for platforms that report it (TikTok today). If a field is absent, the platform does not report it, so read the campaign to confirm. On TikTok, an ad inside an ad group removed in the same request is not deleted separately.\n\n### Fixed\n\n- **Google Ads image extensions accept images from the creative picker.** An uploaded or AI-generated image passed in `extensions.images` (campaign level, or per ad group on Search campaigns) is now attached instead of being refused.\n\n## [1.26.24] - 2026-11-03\n\n### Added\n\n- **manage_social_media: LinkedIn company pages.** Pass `ds_id` LIP to post text, links, images and multi-image posts (now or scheduled) and to list, reply to, delete and turn on or off comments on a LinkedIn page. Instagram (`ds_id` IGI) stays the default.\n\n### Fixed\n\n- **manage_social_media: fewer refused calls.** Mistakes with a clear intent are fixed with a note instead of refused: `wait_seconds` on a non-job status, listing filters on a single-item status, `limit` over 50, `moderation: delete/hide`, `platform`, `upload_refs` as a list. `list_accounts`, `help` and `list` say where to go instead.\n\n## [1.26.23] - 2026-11-03\n\n### Changed\n\n- **TikTok ad groups: the campaign tools now say which pacing and bid values TikTok accepts.** `pacing` takes `PACING_MODE_SMOOTH` or `PACING_MODE_FAST` and `bid_type` takes `BID_TYPE_NO_BID`, `BID_TYPE_CUSTOM` or `BID_TYPE_MAX_CONVERSION`. With campaign budget optimization on, all ad groups share one `optimization_goal` (a new ad group defaults to the first one's) and cost cap is not allowed. A TikTok Business Center identity pairs `identity_type` `BC_AUTH_TT` with `identity_authorized_bc_id`.\n\n## [1.26.21] - 2026-11-02\n\n### Changed\n\n- **TikTok devices: the campaign tools now say what TikTok accepts.** `devices` takes TikTok numeric device model ids, as a campaign read returns them, not device types such as `MOBILE`; target iOS or Android with `platforms`.\n\n## [1.26.20] - 2026-11-02\n\n### Added\n\n- **campaign_and_resource_get: a campaign with many ad groups can be read a page at a time.** With `campaign_id`, set `params.ad_group_limit` (and `params.ad_group_offset` for later pages). Ad groups come back in ID order, and a note gives the total and the next offset. Without `ad_group_limit` and `ad_group_offset` every ad group is returned, as before.\n\n## [1.26.19] - 2026-11-02\n\n### Changed\n\n- **Audience activation now asks before granting Google Ads consent.** When an activation sends to a Google Ads\n  destination, the agent shows the Google Ads consent notice word for word and sets the consent status only from your\n  answer, instead of granting it on its own. Applies to teams with audience activation enabled.\n\n## [1.26.18] - 2026-11-02\n\n### Changed\n\n- **TikTok video ads: the campaign tools now say how to set the cover.** A video ad takes `ad_format` SINGLE_VIDEO, the TikTok video id in `asset_id` and an optional cover image id in `image_ids`; without a cover the video's own cover is used when TikTok provides one.\n\n## [1.26.16] - 2026-11-02\n\n### Added\n\n- **Google Ads: Target Impression Share bidding and images per ad group.**\n  `manage_campaign` documents `bidding_strategy: TARGET_IMPRESSION_SHARE` for Search campaigns with its location, percentage and max CPC settings, and `ad_groups[].extensions.images` to attach image assets to a single Search ad group.\n\n## [1.26.15] - 2026-11-02\n\n### Added\n\n- **Google Ads: pin responsive search ad headlines and descriptions, and set display paths.**\n  `manage_campaign` now accepts headline and description items as `{text, pinned_field}` (`HEADLINE_1`–`3`, `DESCRIPTION_1`–`2`, or `null` to unpin) instead of rejecting them, and documents `path1` / `path2` (up to 15 characters; leave out to keep, `\"\"` to remove).\n  The ad description now says that display path and URL suffix (`url_tags`) edits are made in place and keep the ad's ID, and that re-sending an ad's current creative leaves it as it is.\n\n## [1.26.14] - 2026-11-02\n\n### Changed\n\n- **TikTok locations: the campaign tools now say what TikTok accepts.** `locations` takes country codes or TikTok numeric location ids, not city names, and `location_details` is not supported for TikTok.\n\n## [1.26.13] - 2026-11-01\n\n### Added\n\n- Assistants can now answer buying questions — plans, how accounts are counted toward plan limits (public-data profiles such as Instagram Public Data do not count), what AI credits are spent on, and billing — from a new `pricing_and_purchasing` guide in `supermetrics_guide`. Guides now match how the user is connected: users of the official AI apps no longer see Supermetrics API details such as the API row limit, and every guide says whether the user is on AI Chats or the Supermetrics API.\n\n## [1.26.12] - 2026-10-31\n\n### Fixed\n\n- Creative picker thumbnails in ChatGPT no longer depend on ChatGPT refreshing its stored copy of the picker's security settings.\n\n## [1.26.11] - 2026-10-31\n\n### Fixed\n\n- Studio dashboards built by an AI chat are less likely to show NaN: the dashboard guidance now spells out that the first row of query results holds column names, and an upload that reads values from that row gets a warning to fix it.\n\n## [1.26.10] - 2026-10-31\n\n### Fixed\n\n- The creative picker in ChatGPT shows asset thumbnails again; they were blocked when the picker page and its security settings came from different Supermetrics servers.\n\n## [1.26.9] - 2026-10-31\n\n### Fixed\n\n- The creative picker now loads in Gemini, which previously left it stuck on its loading screen.\n\n## [1.26.8] - 2026-10-30\n\n### Fixed\n\n- A file you upload in the creative picker now reaches the assistant without pressing \"Use Selected Asset\", so you can just tell it you are done and it posts the file instead of opening the picker again.\n\n## [1.26.6] - 2026-10-30\n\n### Added\n\n- Audience activation status now includes the failure reason when a run fails or partially fails, both for the run as a whole and for each destination that failed.\n\n## [1.26.5] - 2026-10-30\n\n### Changed\n\n- **Google Ads: `manage_campaign` now describes in-place responsive search ad edits and per-type extension updates.** Editing only a responsive search ad's headlines, descriptions or final URLs keeps the ad and its ID; other creative changes still replace it. On update, each extension type sent replaces only that type, an empty list removes it, types left out are kept, and locations are never removed. Extensions apply at campaign level only, and images on a responsive search ad update must be sent as campaign image extensions.\n\n## [1.26.4] - 2026-10-30\n\n### Changed\n\n- **TikTok campaigns: tracking a CLICK ad group with a pixel.** Set the pixel on each ad as `platform_settings.tracking_pixel_id` (the numeric pixel id). An ad group `pixel_id` with goal CLICK is sent as `tracking_pixel_id` on its new ads that set none. On an existing ad, the pixel changes only together with a creative change.\n\n## [1.26.3] - 2026-10-30\n\n### Fixed\n\n- When a Google Ads audience call fails because the connection is missing the Data Manager permission, or needs reconnecting, the reconnect link now asks for that permission, so reconnecting fixes the error instead of looping.\n\n## [1.26.1] - 2026-10-30\n\n### Added\n\n- When a campaign update or status change is refused because write access is off for the ad account, the person who connected the account now gets an approval link instead of an error, for teams in the rollout. Approving turns on write access with the approval level \"All live changes\" and applies the change in one step. If the change then fails, the page and the chat say write access is now on.\n\n### Fixed\n\n- The Close button on the approval page no longer replaces the result with \"You can now close this tab\". When the browser keeps the tab open, the result stays on screen with a short hint below it.\n\n## [1.26.0] - 2026-10-30\n\n### Added\n\n- `manage_campaign` now documents `targeting.age_suggestion` for Meta ads: the ages Meta should favour when Advantage+ audience is on, while `age_min` stays 18-25 and `age_max` 65.\n\n## [1.25.15] - 2026-10-30\n\n### Changed\n\n- **Instagram stories: historical analysis now supported.** The AI no longer steers you away from story questions about past periods. Supermetrics can return up to 3 years of Instagram story history, starting from 2026-10-30 or from the date the account's stories were first fetched with Supermetrics, whichever is later.\n\n## [1.25.13] - 2026-10-30\n\n### Changed\n\n- **Google Ads: `manage_campaign` now describes the campaign rules SuperAPI enforces since its recent fixes.** Performance Max asset groups: up to 5 descriptions and 5 videos, a text type sent replaces all of it, at most 20 images (images sent on update replace all of them), a square logo of at least 128x128 (or an `assets` entry with type `logo`), and a new asset group must carry its assets and landing page in the same request, as assets cannot be added later to a group that has none. Campaign-level business name and logo on campaigns without brand guidelines apply only to new asset groups with ads. On a portfolio bidding strategy, sending the portfolio's target keeps the campaign on it. New Demand Gen ad groups take Audience names in `interests`.\n\n## [1.25.10] - 2026-10-29\n\n### Added\n\n- `supermetrics_guide` has a capability guide for each connector that supports campaign management — `google_ads_capabilities`, `facebook_meta_capabilities`, `linkedin_ads_capabilities`, `microsoft_advertising_capabilities`, `tiktok_ads_capabilities`, `chatgpt_ads_capabilities` and `snapchat_marketing_capabilities`. Each lists the operations that connector supports and refuses, the `platform_settings` keys it honours, and the targeting fields it accepts and at which level, so an unsupported request can be avoided rather than discovered from a platform rejection.\n\n### Changed\n\n- The `supermetrics_guide` troubleshooting guide for campaign write access now lists all seven connectors that support campaign management. It had been naming four and describing LinkedIn as read-only.\n\n## [1.25.9] - 2026-10-29\n\n### Fixed\n\n- Discovery, UTM and Instagram scheduling tools no longer hang when saved business context cannot be read. After a few seconds they answer without it.\n\n## [1.25.8] - 2026-10-29\n\n### Changed\n\n- **Confirming a change to a campaign that is not found now says so.** The approval page reports that the campaign was not found in the ad account and nothing was changed, and to wait and ask again if it was created a few minutes ago, instead of \"this change may already have been applied\".\n\n## [1.25.6] - 2026-10-29\n\n### Added\n\n- **Estimate what a Facebook Ads budget can deliver.** `campaign_and_resource_get` with\n  `resource_type='campaign_planner'` returns an optimistic, expected and pessimistic range of impressions,\n  clicks, engagement, video views or landing page views for a budget, benchmarked on similar advertisers'\n  campaigns. It works before any campaign or targeting exists, and complements `forecast`, which returns\n  Meta's or Google's own estimate for targeting you have already defined.\n\n## [1.25.5] - 2026-10-29\n\n### Changed\n\n- **New TikTok ad groups now take the status you ask for.** ENABLED or PAUSED is applied, an ad group without a status is created paused, REMOVED is refused, and each campaign write failure now says what kind of failure it is and which new ad group or ad failed.\n\n## [1.25.3] - 2026-10-29\n\n### Changed\n\n- Instagram publishing is more forgiving: alt text or post options that a carousel, reel or story can't carry are now skipped with a note instead of failing the post. When a file upload never arrived, the error now points to uploading it in the creative picker, and temporary gateway errors from Supermetrics come back as a short \"retry in a minute\" message.\n\n## [1.25.2] - 2026-10-29\n\n### Changed\n\n- Scheduling or rescheduling an Instagram post now states that the publish time must be 5 minutes to 75 days ahead, and that leaving it out publishes right away, so assistants stop picking times that are refused.\n\n### Fixed\n\n- Publishing or using an `upload_ref` whose file was uploaded empty (0 bytes) now fails early with a clear \"no file was uploaded\" error, instead of a \"Media URL could not be fetched (HTTP 416)\" error from the platform.\n\n## [1.25.1] - 2026-10-28\n\n### Fixed\n\n- Creating an ad from a creative picker upload no longer fails when the upload is more than four hours old. The link handed to the ad platform is now renewed each time the upload is used, instead of being reused past its expiry — which made the platform report that it could not fetch the video.\n- Scheduled Instagram videos uploaded through Supermetrics now publish at their scheduled time instead of failing because the video link had expired.\n\n## [1.25.0] - 2026-10-28\n\n### Added\n\n- When a campaign request is blocked because your team has no Campaign Management access, a free Campaign Management trial now starts automatically and the request is completed, instead of returning a licensing error. You'll see a note with the trial's end date and a link to purchase a subscription, and a clear message (never a raw error code) if a trial can't be started.\n\n## [1.24.20] - 2026-10-28\n\n### Changed\n\n- **TikTok campaigns: the campaign tool now tells the model it can set each ad group's schedule.** The ad group `platform_settings` description names `start_date` and `end_date` (UTC), and the campaign `start_date`/`end_date` descriptions say TikTok campaigns have no dates of their own. The note for a started ad group now names `start_date`, `start_time` and `schedule_start_time`.\n\n## [1.24.19] - 2026-10-28\n\n### Changed\n\n- **TikTok Spark Ads: the campaign tool and the TikTok skill reference now tell the model it can send the TikTok account identity.** When it is omitted, the identity is looked up from the post; if the owner cannot be found, the model should send the identity instead of retrying. Campaign reads now show each ad's identity.\n\n## [1.24.18] - 2026-10-28\n\n### Fixed\n\n- Instagram story sequences are now limited to 10 frames up front, so the assistant no longer submits longer sequences that Instagram rejects.\n\n## [1.24.17] - 2026-10-27\n\n### Changed\n\n- When `manage_social_media` fails because of a missing license or an expired trial, the error now says that the Instagram Insights (IGI) data source must be included in your license.\n\n## [1.24.16] - 2026-10-27\n\n### Fixed\n\n- **OAuth: strict MCP clients such as Databricks can now complete sign-in.** Each MCP path (`/mcp`, `/platform` and every per-data-source path) now serves its own protected resource metadata at `/.well-known/oauth-protected-resource/<path>`, whose `resource` is that path's URL, and a 401 on the path points there, as RFC 9728 requires. The root document at `/.well-known/oauth-protected-resource` is unchanged.\n\n## [1.24.15] - 2026-10-27\n\n### Added\n\n- LinkedIn campaigns and ad sets can now report the `DRAFT` status, and `campaign_and_resource_get` accepts `status=DRAFT` to filter for draft campaigns on LinkedIn (other platforms still treat a `DRAFT` filter as `PAUSED`).\n\n### Changed\n\n- **TikTok Smart+: a change that includes fields TikTok does not allow is normally refused before anything is sent.** The response lists what can be changed on Smart+ (campaign name, budget_amount and status; ad group budget_amount, only when campaign budget optimization is off, and status; budget_type cannot be changed) and tells you whether anything was applied, so the same change is not resent.\n\n## [1.24.12] - 2026-10-27\n\n### Fixed\n\n- Publishing to Instagram or using an uploaded creative in a campaign now says clearly when an image or video was never actually uploaded, and suggests the upload picker, instead of failing with a long storage URL and a 404. The assistant is also told which Instagram options apply to each post type (for example, alt text, tags and location are not allowed on carousels), so it stops sending options Instagram rejects.\n\n## [1.24.11] - 2026-10-27\n\n### Added\n\n- Data source discovery now marks Instagram Insights as supporting social media management, so the assistant suggests moderating comments and publishing posts alongside analytics.\n\n## [1.24.10] - 2026-10-27\n\n### Changed\n\n- **AI images: the assistant asks before using them, and the picker can open on earlier images.**\n  Campaign and Instagram flows now tell the assistant to ask whether the user wants to see AI-generated images first, and creative_picker accepts `focus_upload_refs` to show previously generated images first, preselected.\n- **Creative picker: AI-generated images are named after their prompt.**\n  Picked images now reach the assistant as e.g. `ai_cat-wearing-sunglasses_3d2c756bcb28.png` instead of `ai_gen_3d2c756bcb28.png`, so it can tell them apart.\n- **campaign_and_resource_get `assets` also lists saved uploads and AI images.**\n  Results include a `saved` list (upload_ref, filename) next to the platform library, and IGI returns its saved images instead of failing, so the assistant can find an existing image without opening the creative picker.\n\n### Fixed\n\n- When Supermetrics briefly returns a gateway or server error page, the assistant now gets a short error such as \"HTTP 502: Bad gateway\" instead of the full web page, which could fill tens of thousands of tokens of the conversation.\n\n## [1.24.6] - 2026-10-27\n\n### Added\n\n- **TikTok Ads: ad groups accept custom bids.**\n  Send `bid_type` `BID_TYPE_CUSTOM` with `bid_price` or `conversion_bid_price` in the ad group's `platform_settings`.\n\n### Changed\n\n- **TikTok Ads: a running ad group's start date is no longer sent again.**\n  When a campaign update cannot change the start of an ad group that already started, the result says so and tells the assistant not to resend it.\n\n## [1.24.0] - 2026-10-26\n\n### Added\n\n- **New `activate-audience` prompt walks you through sending an audience to an ad platform.**\n  Where the client supports MCP prompts, it guides picking the source data and identifier fields, choosing or\n  creating the destination audience, and confirming before anything is saved, created or run. It appears only for\n  teams with audience activation enabled.\n\n## [1.23.15] - 2026-10-26\n\n### Changed\n\n- **Campaign tools: ad set and ad group budgets are described correctly for Meta and TikTok.**\n  The tool descriptions now say that Meta campaigns without budget optimization carry the budget and bid strategy on each ad set, and that TikTok campaigns without it need a budget on each ad group when creating two or more.\n\n## [1.23.11] - 2026-10-25\n\n### Added\n\n- manage_user_and_team login_data_source can request a login link with the data source's write permissions (include_management_scopes).\n\n### Changed\n\n- After a campaign change is approved, checking its approval status now returns what the write itself returns.\n\n### Fixed\n\n- **Clearer parameter errors.** Errors from cross-field checks no longer start with `: Value error,`, and\n  account-not-available guidance on tools that take `account_id` names that parameter and the right `ds_id`.\n- Approval links for campaign changes show the account name again instead of only its ID.\n\n## [1.23.9] - 2026-10-25\n\n### Changed\n\n- Tools that both read and changed data are now split into a read tool and a write tool: `get_user_and_team` / `manage_user_and_team`, `get_support_tickets` / `contact_supermetrics`, `get_business_context` / `manage_business_context`, and `get_dashboards` / `manage_dashboards`. Each tool advertises only the operations it is for, and its safety hints (read-only, destructive, open-world) now match what it actually does. Existing calls keep working: the `manage_*` tools still accept the read actions, and the read tools refuse write actions with an error naming the tool that performs them.\n\n## [1.23.8] - 2026-10-24\n\n### Changed\n\n- Building a Supermetrics Studio dashboard on BigQuery data now has its own `supermetrics_guide` how-to (`dashboard_bigquery`), and the dashboard and campaign guidance the server gives AI clients is more neutral and client-agnostic.\n\n## [1.23.7] - 2026-10-24\n\n### Changed\n\n- Connection and reconnect messages now name the Supermetrics team and login the AI connector reads from, so a connection made while signed in with another email or in another team is no longer a silent dead end.\n\n## [1.23.6] - 2026-10-24\n\n### Added\n\n- A new Live Dashboards skill guides AI agents through planning and publishing live Supermetrics Studio dashboards, including dashboards with campaign actions such as pausing a campaign or changing a budget. Skills now also show readable names and icons in ChatGPT and Codex. The `budget-pacing-and-allocation` skill is renamed `budget-pacing-allocation`; clients that imported it under the old name pick up the new one on their next skill refresh.\n\n### Changed\n\n- Tool input schemas now advertise each parameter's allowed values and numeric bounds, including for optional fields, so clients can validate arguments before calling instead of inferring the domain from description text. Descriptions keep the guidance on which value to choose.\n\n## [1.23.5] - 2026-10-23\n\n### Added\n\n- `supermetrics_guide` has a new `google_sheets` how-to. When you ask Claude to put Supermetrics data into a Google Sheet, it builds the sheet so the Supermetrics for Google Sheets add-on refreshes it automatically on a schedule, and you can edit each query in the add-on. Not offered in Supermetrics Studio or ChatGPT.\n\n## [1.23.3] - 2026-10-23\n\n### Changed\n\n- **`manage_campaign`: TikTok guidance is shorter and names the values TikTok accepts.** `pixel_event` now lists TikTok's optimization events (`SHOPPING` for complete payment, `ON_WEB_CART`, `ON_WEB_REGISTER`) instead of `COMPLETE_PAYMENT`, `optimization_goal` names `SHOW` (TikTok has no `IMPRESSION` goal), and `billing_event` names the value TikTok pairs with each goal. A TikTok refusal for an outstanding payment now also gets the payment note.\n\n## [1.23.2] - 2026-10-23\n\n### Changed\n\n- Claude and ChatGPT no longer open support tickets for cancelling a subscription bought online. They walk you through **Cancel subscription** on the Hub instead.\n\n## [1.22.11] - 2026-10-22\n\n### Changed\n\n- Campaign updates: the `budget_type` guidance now says to leave it out on an update to keep the campaign's current budget type; when only `budget_amount` is sent, TikTok and Snapchat campaigns with no campaign-level budget get a daily one, and Meta campaigns with ad set budgets are refused.\n\n## [1.22.9] - 2026-10-22\n\n### Added\n\n- The server now publishes Supermetrics skills through MCP skill discovery: clients that support it can list and import thirteen workflow skills, from getting started and querying marketing data to campaign management, wasted-spend audits, budget pacing, ecommerce ROAS, executive reporting, funnel and tracking audits, B2B pipeline, SEO and content, and event ROI.\n\n## [1.22.8] - 2026-10-22\n\n### Fixed\n\n- TikTok Ads: the `manage_campaign` guidance for campaign budget optimisation (`budget_optimize_switch`) now says it can only be set when a campaign is created, and that ad groups in a CBO campaign must not have their own budget.\n\n## [1.22.5] - 2026-10-21\n\n### Changed\n\n- `manage_user_and_team` (`get_info`): when reading your user and team details fails, the error may now include the reason from Supermetrics, such as a missing permission or scope. These errors never include raw response bodies, and network errors and timeouts now say what happened.\n\n### Fixed\n\n- The license warning (for example, a trial or subscription that ends soon) is no longer lost when the first call in a session is a `manage_user_and_team` action other than `get_info`, or a failed user and team read: the warning now shows on a later call.\n\n## [1.22.4] - 2026-10-21\n\n### Added\n\n- `manage_campaign` shows a do-not-resend note when the connector reports a TikTok Smart+ refusal reason. Campaign write failures can carry a machine-readable `reason`.\n\n### Changed\n\n- Campaign writes are no longer retried after the ad platform rate limits them. The approval page now says \"rate limited, try again later\" or \"platform unavailable, not applied\" instead of \"rejected\" or \"unknown outcome\". The log events `tool_params_unknown` and `parameter validation failed` are replaced by `tool_input_rejected`.\n- When TikTok refuses a change because the ad account's payment is incomplete, the approval page, `get_approval_status` and the `manage_campaign` result now say to complete payment in TikTok Ads Manager instead of asking to fix the input.\n- `manage_campaign` now documents the TikTok objective values `WEB_CONVERSIONS` and the others TikTok accepts, says that `WEB_CONVERSIONS` needs `pixel_id` and `pixel_event` in the ad group `platform_settings`, and documents the `CONVERT` optimization goal.\n\n## [1.22.3] - 2026-10-21\n\n### Added\n\n- `manage_campaign` shows a do-not-resend note when the connector reports a TikTok Smart+ refusal reason. Campaign write failures can carry a machine-readable `reason`.\n\n### Changed\n\n- Campaign writes are no longer retried after the ad platform rate limits them. The approval page now says \"rate limited, try again later\" or \"platform unavailable, not applied\" instead of \"rejected\" or \"unknown outcome\". The log events `tool_params_unknown` and `parameter validation failed` are replaced by `tool_input_rejected`.\n\n## [1.22.2] - 2026-10-21\n\n### Added\n\n- `data_query` has a new `fresh` option. It skips stored query results and runs the query again, so a change you just made (for example a new ad set budget) can show up straight away. Where the platform honours it, the response shows `cache_used: false`; otherwise a note says the fresh read was not applied. It is not available for connections that use an API key, and needs campaign write access on every queried account. Some data sources keep their own short-lived cache, so a value may still lag on those. Use it only to confirm a change right after a write; it is slower and uses more quota.\n\n## [1.22.0] - 2026-10-20\n\n### Fixed\n\n- The campaign approval page now gives the real reason for three refusals that it showed as an ad platform rejection. Supermetrics blocked the change (write access, budget guardrail, subscription, or allowed accounts). The connected user has no role that can edit the ad account. The ad platform is busy. If the user opens a link that was already used, the page gives the same reason. If the agent checks the status of such an approval, it learns that nothing was applied and what to do next: tell the user why Supermetrics blocked the change, get a role on the ad account, or submit the change again in a few minutes. If an unexpected error in Supermetrics stops the change, the page names that error. It also says that the outcome is unknown.\n\n## [1.21.10] - 2026-10-20\n\n### Fixed\n\n- When a campaign change is refused because your Supermetrics API key or sign-in lacks permission for campaign changes, the error now says so and explains how to get that permission, instead of saying the data source connection expired and sending you to reconnect it, which could never help.\n\n## [1.21.9] - 2026-10-20\n\n### Added\n\n- The UTM builder and auditor now return a corrected version of each link straight away, with casing and separators fixed to your conventions, together with a list of what was changed and any issues that still need your decision (such as a source that isn't on your approved list). The assistant shows the fixed link in the same reply instead of waiting to be asked.\n\n### Changed\n\n- The safety check now accepts a domain or an email address, so you can screen a cold-pitch sender directly, shows when the domain was registered, and treats a sender with no working website as a warning sign instead of a failed check. The link check now follows HTML meta-refresh redirects, which many QR-code tools use, so it catches UTMs lost there, and it warns when a page redirects with JavaScript that can't be followed.\n\n## [1.21.7] - 2026-10-19\n\n### Changed\n\n- **Instagram Explore is no longer suggested as an ad placement.** Meta removed the Explore feed placement, and ad sets that specify it are rejected, so the campaign tools no longer list it among the example placements.\n\n## [1.21.6] - 2026-10-19\n\n### Changed\n\n- **Campaign tools: \"account not available\" errors explain how to connect another login.** When the requested account is in none of the team's connections, the error now also points to `manage_user_and_team` (`login_data_source`) for a login link, in case the account belongs to a login that isn't connected yet.\n\n### Fixed\n\n- **Data queries: the connect link is back on \"no active connections\" errors.** `data_query` and `get_async_query_results` now add the data source connect link based on the error code (`QUERY_AUTH_*`), so rewording the API message no longer drops it.\n\n## [1.21.3] - 2026-10-16\n\n### Fixed\n\n- **Campaign approval page: a failed save of the result no longer ends in a bare server error.**\n  When the change was applied but its result could not be saved, the page now shows that the\n  result is unknown, so you can check the campaign before you try again.\n\n## [1.21.2] - 2026-10-16\n\n### Fixed\n\n- When a campaign change fails because write access is off, the link in the error now opens Campaign Write Access in the team your AI connection uses, instead of whichever team your browser had open. The AI is now told that no reconnect is needed, and that you must be signed in to the Hub with the same email as your AI connection.\n\n## [1.21.1] - 2026-10-16\n\n### Changed\n\n- **manage_campaign: Performance Max business name and logo are now documented.** `business_name` and `logo_url` / `logo_id` / `logo_data` / `logo_prompt` are listed in the Google Ads Performance Max `platform_settings` and apply on create and update; the creative fields say a logo goes in `logo_*`, not in `assets`.\n\n## [1.21.0] - 2026-10-16\n\n### Added\n\n- Google Ads `platform_settings` now documents `ai_max_enabled` and `final_url_expansion` for Search campaigns (previously `final_url_expansion` was documented for PMax only).\n\n## [1.20.0] - 2026-10-16\n\n### Added\n\n- Performance Max ads in Google Ads can now be created with multiple long headlines (up to 5).\n\n## [1.19.0] - 2026-10-15\n\n### Changed\n\n- **manage_campaign: targeting updates now keep omitted fields on every platform.** Send only the targeting you want to change; a field you send replaces that field, and an empty list clears it (not on Snapchat). On TikTok and LinkedIn, change an existing ad group's targeting through `ad_groups[].targeting`.\n\n## [1.18.5] - 2026-10-15\n\n### Added\n\n- The campaign approval page shows which connected user the change will run as, so you can see who the ad platform will record as its author before you approve.\n\n## [1.18.1] - 2026-10-13\n\n### Changed\n\n- `GET /mcp` (and the `/platform` and per-data-source aliases) now answers 405 instead of opening an event stream that never carried any messages. MCP clients treat this as \"no server-to-client stream\" and keep working as before; resuming an interrupted response with `Last-Event-ID` is unaffected.\n\n## [1.18.0] - 2026-10-13\n\n### Changed\n\n- **manage_campaign: on Google Ads and Meta, a targeting update keeps the fields you leave out.** Send only the targeting you want to change; an empty list (e.g. `locations: []`) clears that field. On Google Ads, existing ad groups no longer take campaign-level targeting from the same update. Other platforms still replace targeting, so send the full set there.\n- Snapchat Ads campaign tools now document sub-country targeting via `location_details`: region, metro and zip are supported, and any other type refuses the ad group instead of targeting the whole country.\n- Snapchat Ads campaign tools state budget minimums in the ad account's currency (20 per campaign, 5 daily per ad squad) instead of US dollars.\n\n### Fixed\n\n- **Snapchat: `manage_campaign` now says how to create a website ad.** Set the ad type as `creative.type`. Without a type, a landing page makes the ad a website ad (`REMOTE_WEBPAGE`). Every website ad needs a `call_to_action`; a plain `SNAP_AD` takes none.\n\n## [1.17.8] - 2026-10-12\n\n### Changed\n\n- When a query fails because no subscription covers your AI chat, or because a trial expired after you bought a plan, the assistant now names your connected team and your other teams and walks you through the fix: reconnect with the team or email that paid, reconnect to pick up a new plan, or swap a destination to AI Chats. It opens a support ticket only if these steps do not help.\n\n## [1.17.7] - 2026-10-12\n\n### Changed\n\n- **`accounts_discovery`: finding an account by name or number is more forgiving.**\n  Account numbers now match in any format (`123-456-7890`, `1234567890`, `act_…`), and names ignore\n  accents, spaces and punctuation (\"Sun Sea Sand\" finds \"Sun, Sea, Sand!\"). Typos are still not\n  matched. When nothing matches, the response says what was compared and suggests checking the full\n  list or reconnecting the data source.\n\n### Fixed\n\n- **`accounts_discovery`: an ad account created or shared after you connected now shows up without reconnecting.**\n  When a search by name or number finds nothing in the stored list, or the stored list is empty, the\n  tool re-reads the account list from the platform once and searches again. Previously only\n  connections made in the last hour were re-read, so newer accounts stayed hidden until the data\n  source was reconnected.\n\n## [1.17.6] - 2026-10-09\n\n### Changed\n\n- `manage_dashboards` now documents which BigQuery tools Studio boards can call (`execute_sql_readonly` and the dataset/table metadata tools), their parameters and response format, and how to scope BigQuery projects in `allowed_accounts`, so AI-built BigQuery boards work on first upload.\n\n## [1.17.5] - 2026-10-09\n\n### Changed\n\n- When a trial user asks to cancel their trial, the assistant now confirms that the trial needs no card and expires automatically without a charge, instead of opening a support ticket. Cancellation tickets are now only for paid subscriptions and account deletion requests.\n\n## [1.17.4] - 2026-10-09\n\n### Fixed\n\n- Direct tool calls (`POST /mcp/{tool}`) now return a 400 for a request body that is not a JSON object, and a validation error for a non-text `ds_id`, instead of a 500.\n\n## [1.17.3] - 2026-10-09\n\n### Added\n\n- **Google Ads: `network_settings.search_partners` is now documented.** It controls Search partners separately from Google Search; on create it defaults to the `search` value. Reading and setting it ships with the paired SuperAPI change and is visible once that is deployed.\n\n## [1.17.1] - 2026-10-08\n\n### Fixed\n\n- Support tickets created through `contact_supermetrics` now get the right Zendesk category (authentication, billing, subscription, cancellation, data discrepancy or query help) instead of always defaulting to query help.\n\n## [1.17.0] - 2026-10-07\n\n### Added\n\n- **Campaign management: keyword bids and a Maximize Clicks max CPC are now documented.**\n  `keywords` and `add_keywords` accept a per-keyword `cpc_bid`, and Google Ads `bidding_config` accepts `target_spend_cpc_bid_ceiling` to cap CPC on Maximize Clicks.\n- A change sent for approval now returns an `approval_ref`. After the user approves, `campaign_and_resource_get` with `resource_type: approval_status` reports whether the change was applied, partly applied, rejected by the platform, failed, needs a reconnect, is still pending, was submitted but has no result yet, expired unused, or could not be checked. Opening or clicking an approval link a second time now shows what happened to the change instead of reporting the link as expired.\n- Google Ads shared negative keyword lists: `manage_campaign` accepts `platform_settings.negative_keyword_lists` to create, sync and attach/detach account-level lists, campaign reads show attached lists, and `campaign_and_resource_get` gains `resource_type` `negative_keyword_lists`\n\n### Changed\n\n- **Google Ads: new ad groups now take the status you ask for.** An ad group created as ENABLED is created enabled instead of paused, so it no longer needs its own activation call; it still serves only once its campaign is enabled. Ad groups without a status are still created paused, and an ad group asking for REMOVED is refused.\n- Approval links for campaign changes now stay valid for 30 minutes instead of 15.\n\n### Fixed\n\n- **`data_query`: results cut at `max_rows` now say so when they come back inline.** The likely-truncated note already shown by `get_async_query_results` now also appears on rows returned directly by `data_query`.\n- Tools now say which parameters they ignored, and suggest the right name where there is one, for example `filter` instead of `search` on `accounts_discovery`, instead of silently returning unfiltered results.\n- `field_discovery` with a broad `filter` returns at most 150 fields, so filtered responses no longer exceed client token limits. Exact name matches always come back and are listed first, then partial name matches, then fields that match only on description. A note gives the total number of matches and how to narrow the filter. Filtering by a field type or report type still lists every matching field.\n\n## [1.16.44] - 2026-10-07\n\n### Added\n\n- `data_query` now accepts `compress`. When a query finishes immediately, its rows come back as the same compact table that `get_async_query_results` returns.\n\n### Changed\n\n- **Account-limit errors are explained as a plan limit.** The assistant now offers to add accounts on the subscription page first and to swap the included accounts as the alternative, instead of passing the \"not listed as a prioritised account\" message through unexplained.\n- Compressed query results from `get_async_query_results` are now one compact table whose columns are your requested field IDs, so they use about 19% fewer tokens. The display-name header row is no longer included in compressed output.\n\n## [1.16.43] - 2026-10-06\n\n### Fixed\n\n- A tool that is not available for your account is now refused before the tool is prepared, so the refusal is what you receive even when the tool itself fails to start. Previously a tool that failed to start could replace the refusal with a generic execution error.\n\n## [1.16.42] - 2026-10-06\n\n### Changed\n\n- Compressed `field_discovery` and `accounts_discovery` responses are now returned as compact tables, using 15–25% fewer tokens. Optional values a row lacks show as empty cells, and list values are joined with `|`.\n- Studio dashboards built through `manage_dashboards` now get a warning on upload if their queries ask for compressed results, which boards cannot read.\n\n### Fixed\n\n- Data source logos at `https://mcp.supermetrics.com/logos/{id}` are now reliably saved when data sources are listed, so they show the correct logo instead of a generic placeholder.\n\n## [1.16.41] - 2026-10-06\n\n### Fixed\n\n- Data source logos at `https://mcp.supermetrics.com/logos/{id}` now show the correct logo for every public data source straight away, instead of a generic placeholder until the source had been looked up in a chat.\n\n## [1.16.40] - 2026-10-06\n\n### Changed\n\n- `data_source_discovery` no longer lists a logo URL for every data source. A single note gives the URL pattern instead (`https://mcp.supermetrics.com/logos/{id}`), which serves every source's logo from the MCP server's own domain, so the data source list is roughly 30% smaller.\n\n## [1.16.37] - 2026-10-05\n\n### Removed\n\n- Query results no longer append cross-platform comparison suggestions or notes about data sources that aren't connected.\n\n## [1.16.36] - 2026-10-04\n\n### Changed\n\n- Asking Supermetrics what's new now lists the latest additions and changes from the changelog, so it is always current, and the capability tour now includes the free marketing checks for links, landing pages and ad copy.\n\n## [1.16.32] - 2026-10-02\n\n### Fixed\n\n- Tool calls no longer fail with \"Unknown parameter(s)\" when they include a parameter the tool does not use, such as `compress` on `data_query`. The tools ignore such parameters again, as they did before the last release. Only marketing_utilities still corrects slightly misspelled parameter names and reports unknown parameters as an error.\n\n## [1.16.31] - 2026-10-02\n\n### Changed\n\n- Successful data queries no longer suggest turning the results into a Supermetrics Studio dashboard.\n\n## [1.16.29] - 2026-10-01\n\n### Added\n\n- The UTM builder recommends each ad network's medium and dynamic macros, and both UTM actions flag a macro written in another network's format, which that network would leave unfilled. Meta, LinkedIn and Snapchat `{{...}}` macros are no longer URL-encoded, so those platforms fill them in correctly, and mediums such as `paid-social` are no longer wrongly flagged as unassigned in GA4.\n\n### Changed\n\n- Page speed checks now answer within about 45 seconds: if pages are still being tested, the response says so and returns a job ID the assistant can use to fetch the results a little later, instead of timing out. Checks queue automatically when Google's PageSpeed service is busy rather than failing, and results are reused for 24 hours across all users, so repeat checks of the same page return instantly (ask for a fresh test after changing the page). The character-limit checker understands common platform names such as \"google\", \"facebook\" and \"twitter\", adds Google Ads callout, sitelink, display path, long headline and business name limits, and accepts up to 200 texts at once. Asking the tool for \"help\" lists what it can do, and pages that block Google's automated test are explained more clearly.\n\n## [1.16.26] - 2026-09-30\n\n### Fixed\n\n- Tools now correct slightly misspelled parameter names and option values (for example `platform` for `platforms`, or `Meta` for `meta`) and say so in a note, recover obviously misplaced input in marketing_utilities (ad copy sent as `urls`, `domains` for email_dns), and report unknown parameters as an error instead of silently ignoring them.\n\n## [1.16.24] - 2026-09-30\n\n### Fixed\n\n- **Google Ads: `geo_target_type` and `network_settings` are now documented where they actually work.**\n  `geo_target_type` was described only under `ad_groups[].platform_settings`, which is the one place SuperAPI ignores it — it is a campaign-level setting, so send it in the campaign `platform_settings` (`PRESENCE`, `PRESENCE_OR_INTEREST`, or `SEARCH_INTEREST` for Search and standard Shopping campaigns). `network_settings` (`{search, display}`) is now documented too. The behaviour these describe — an ad-group value being reported as ignored, and a SEARCH campaign defaulting to `display: false` — ships with the paired SuperAPI change and is visible once that is deployed.\n- **Google Ads: the EU political-ads declaration is no longer lost when sent inside `platform_settings`.** A `contains_eu_political_ads` value placed there is now honoured instead of being replaced by the default.\n\n## [1.16.23] - 2026-09-30\n\n### Added\n\n- The public documentation page now describes the marketing_utilities tool and its actions.\n\n## [1.16.22] - 2026-09-30\n\n### Removed\n\n- Optional `request` argument on `field_discovery`, `accounts_discovery`, `data_query` and\n  `instagram_insights` is removed now that the time-boxed diagnostics collection has closed.\n  Clients that still send it are unaffected: the value is dropped before the call runs.\n\n## [1.16.21] - 2026-09-30\n\n### Added\n\n- `marketing_utilities` gains three more free checks: `link_preview` shows how a link will look when shared on LinkedIn, Facebook, X and Slack and flags missing or badly sized images and truncated titles; `email_dns` explains a domain's SPF, DKIM, DMARC, MX and BIMI setup in plain language; and `char_limits` measures ad and social copy exactly as Google Ads, Meta, LinkedIn and X count it.\n\n## [1.16.20] - 2026-09-30\n\n### Added\n\n- New `marketing_utilities` tool, free to use without a Supermetrics subscription or connected data source: build tracked campaign URLs (`utm_build`) and audit existing ones (`utm_parse`) against your team's UTM conventions, with platform-macro preservation and GA4 attribution checks. Every result reports a status and a list of findings.\n- `marketing_utilities` can now check landing pages with Google PageSpeed Insights (`pagespeed_check`): send up to 10 URLs at once and get performance, accessibility, best-practices and SEO scores, Core Web Vitals, and the top fixes for each page. No data source login needed.\n- `marketing_utilities` can now check whether your tracking survives redirects (`link_check`): send up to 50 links and see which UTM and click-id parameters (gclid, fbclid, msclkid and more) reach the landing page, where any were dropped, and which links end on a broken page. Pages behind bot protection are marked unverified rather than broken. No data source login needed.\n- `marketing_utilities` can now safety-check your links before you launch (`safety_check`): send up to 50 links and every site they redirect through is checked for malware and phishing flags, broken or soon-expiring security certificates, and domains that are about to expire or were only just registered. No data source login needed.\n- `marketing_utilities` can now show how fast your site feels to real visitors over time (`web_vitals_trend`): send up to 50 sites or pages and get about six months of real-user Core Web Vitals from Chrome, with a good or poor rating, whether each metric is improving or getting worse, and when a rating changed. No data source login needed.\n\n### Fixed\n\n- Business context can now be saved as a JSON object, not only as plain text.\n\n## [1.16.19] - 2026-09-29\n\n### Changed\n\n- **Google Ads campaigns can now declare whether they contain EU political ads.** Google requires advertisers to make this declaration. Pass `contains_eu_political_ads` when creating a Google Ads campaign, or when changing the location targeting of one that has never been declared. If it is left out, the campaign is declared as not containing EU political ads and the response says so. A campaign that already has a declaration is never changed.\n- `data_source_discovery` now omits the `data_out` flag on sources where it is false, and drops `categories` when it is empty, keeping responses smaller.\n\n## [1.16.18] - 2026-09-28\n\n### Fixed\n\n- Inline image uploads through the creative picker no longer fail when the base64 is missing padding or uses the URL-safe alphabet — both are now accepted. When the image bytes never actually arrive (a placeholder or a truncated attachment), the error now explains that and points to the upload widget, a public image URL, or a prior upload instead of reporting invalid base64.\n\n## [1.16.16] - 2026-09-25\n\n### Added\n\n- `data_source_discovery` now marks your team's Custom Data Import connector with `is_custom_data_import: true` when listing data sources, so it can be told apart from other private connectors.\n\n## [1.16.14] - 2026-09-25\n\n### Added\n\n- Successful data queries now occasionally suggest turning the results into a live, shareable Supermetrics Studio dashboard, for teams that have not yet published one.\n- Supermetrics can now surface short, targeted announcements about new releases and known issues as a note on tool responses.\n\n## [1.16.13] - 2026-09-25\n\n### Fixed\n\n- `accounts_discovery` now explains *why* an account list is empty when a freshly connected token's live sync failed upstream, instead of always showing the generic \"No accounts found, please connect\". A provider \"access denied\" (e.g. a brand-new Google Ads account whose API access has not propagated yet) tells the user to wait and retry rather than reconnect; a real access gap points to the connect link. Requires the companion superapi change that returns `meta.account_sync_error`.\n\n## [1.16.12] - 2026-09-24\n\n### Added\n\n- **Meta campaigns: you can now set which country a special ad category applies to.**\n  `platform_settings.special_ad_category_country` (an ISO alpha-2 list, e.g. `[\"NO\"]`) is accepted when\n  creating or updating a Meta campaign, and is returned in `platform_details` when you read one. Housing,\n  employment, credit and social-issue campaigns previously had no way to say this through the connector, so\n  Meta fell back to the ad account's registered tax country — silently scoping the campaign to the wrong\n  country for anyone advertising outside where their account is domiciled. Declaring a category without a\n  country now also gets a note back from the Meta connector saying so.\n\n## [1.16.11] - 2026-09-23\n\n### Added\n\n- Optional `request` argument on `field_discovery`, `accounts_discovery`, `data_query` and\n  `instagram_insights` is back, for a time-boxed diagnostics collection: a short statement of\n  the user's task, recorded for quality diagnostics. It does not affect execution, permissions,\n  results or caching, and is never sent upstream. It will be removed again once the collection\n  window closes.\n\n### Fixed\n\n- WooCommerce queries and account discovery no longer fail with \"Data source WooCommerce (WOO) is not available in your license\" when WooCommerce is connected. Requests for `WOO` (or `WC`, `WooCommerce`) are now routed to the live WooCommerce connector instead of the retired one that shares its name.\n\n## [1.16.10] - 2026-09-23\n\n### Fixed\n\n- **`manage_dashboards` listing no longer fails when the client omits paging options.** A bare `list` request (no `limit`/`offset`) from clients that send those optional fields as explicit `null` was rejected with an \"Input should be a valid integer\" error; such nulls now fall back to the defaults, so listing works without specifying paging.\n\n## [1.16.9] - 2026-09-23\n\n### Added\n\n- **`manage_dashboards` can now list your dashboards.** The new `list` action returns the dashboards you own or have been shared with — titles, links, and metadata, newest first — with `limit`/`offset` paging and an optional `filter` to search by id, title, description, or tag, so you can find a board to open or edit without already knowing its ID.\n\n## [1.16.8] - 2026-09-23\n\n### Added\n\n- Successful data queries now occasionally suggest turning the results into a live, shareable Supermetrics Studio dashboard, for teams that have not yet published one.\n\n## [1.16.7] - 2026-09-22\n\n### Changed\n\n- **Field descriptions with load-bearing usage constraints are no longer truncated.**\n  The field list now honors a `preserve_full_description` flag from the backend, so\n  warnings like \"cannot be split by a date dimension\" always reach you whole instead\n  of being cut short in large result sets. These per-connector notes now come from the\n  Supermetrics backend rather than being hardcoded here.\n\n## [1.16.6] - 2026-09-22\n\n### Fixed\n\n- **Authentication now rejects requests with a missing or malformed `Authorization` header instead of falling back to a server-configured key.** Previously, when `SUPERMETRICS_API_KEY` was set in the server environment, a request with no bearer token or a non-`Bearer` header was served using that key rather than being rejected; such requests now receive a 401.\n- **The direct tool path (`POST /mcp/{tool}`) now enforces the same request-body size cap as the `/mcp` JSON-RPC path.** An oversized request is rejected with 413 — whether it declares an over-cap `Content-Length` (previously the connection hung) or streams an over-cap body with no `Content-Length` at all (previously read into memory unbounded). Both paths now share the same protection.\n\n### Removed\n\n- The optional `request` argument on `field_discovery`, `accounts_discovery`, `data_query` and\n  `instagram_insights` has been removed. It was recorded for quality diagnostics only and never\n  affected execution, results or caching.\n\n## [1.16.4] - 2026-09-21\n\n### Added\n\n- Meta ad sets: the EU transparency fields are now documented on `manage_campaign`. Pass `dsa_beneficiary` and `dsa_payor` in an ad set's `platform_settings` to name the legal entity being promoted and the one paying — without them, Meta can reject an EU-targeted ad set.\n\n## [1.16.3] - 2026-09-18\n\n### Added\n\n- Optional `request` argument on `field_discovery`, `accounts_discovery`, `data_query` and\n  `instagram_insights`: a short statement of the user's task, recorded for quality diagnostics.\n  It does not affect execution, permissions, results or caching, and is never sent upstream.\n\n### Changed\n\n- **`manage_dashboards`: board-authoring guidance now forbids displaying data the query didn't return.**\n  The values a board shows must come from the fetched results, never from a hardcoded table/lookup/join baked into the code (static UI text like a KPI title is fine); the AI should say so when the data can't provide what was asked, and any deliberate example data must be visibly labelled as example.\n\n## [1.16.2] - 2026-09-18\n\n### Added\n\n- **`data_source_discovery` now tells you which connectors can receive activated audiences.** Each listed source carries a `data_out` flag (`true` for data-out-capable connectors such as Google Ads and Meta), sourced from the Supermetrics API so there is one source of truth for every client.\n\n## [1.16.0] - 2026-09-17\n\n### Added\n\n- **New `/migrate-data-studio-to-sm-studio` prompt.** Paste a link-shared Google Data Studio report URL and get back step-by-step instructions for rebuilding it as a Supermetrics Studio dashboard — pages, charts, data sources and field bindings. Run it from your client's slash-command menu; it reads the report's structure only, never its data. Available in clients that support MCP prompts, such as Claude Code and Claude Desktop.\n\n### Changed\n\n- **AI-built boards now scope to the accounts they use instead of all accounts.** The `manage_dashboards` `allowed_accounts` guidance no longer presents `{\"*\": [\"*\"]}` (all of the owner's accounts) as the default for new boards — it tells the assistant to list only the accounts the board actually queries. In owner-auth mode every viewer queries on the board owner's credentials, so this stops new boards from unintentionally exposing the owner's other accounts. The all-accounts wildcard remains available for genuinely interactive boards where viewers pick their own accounts.\n\n## [1.15.13] - 2026-09-15\n\n### Changed\n\n- Discovery tools now flag when a team has no saved business context yet and suggest capturing durable guidelines, preferences, or naming conventions — so they persist across sessions instead of being re-explained each time.\n\n### Fixed\n\n- **Data queries now tell you when SuperAPI adjusted your date range.** When requested dates fall outside what a metric supports — e.g. Instagram's \"New followers\" only covers the last 30 days excluding today — SuperAPI clamps the range to the supported window and returns the data instead of failing. That adjustment note was being dropped; the assistant now surfaces it, so a query that quietly returned a narrower window no longer looks like it ignored the dates you asked for.\n\n## [1.15.12] - 2026-09-14\n\n### Added\n\n- The server now answers at per–data-source paths such as `/google-ads` and `/meta-ads`, each offering the same tools and sign-in as the main `/mcp` endpoint, so you can connect a data-source-specific Supermetrics app in ChatGPT.\n\n## [1.15.11] - 2026-09-14\n\n### Changed\n\n- **Documented the AW `manage_campaign` ad_schedule shape.** The `platform_settings` help now spells out that `ad_schedule` is a list of `{day_of_week: MONDAY..SUNDAY, bid_modifier}` where `bid_modifier` is a Google Ads multiplier in 0.1–10 (0.7 = −30%, 1.3 = +30%, the same convention as `bid_adjustments`) that sets a day-of-week bid modifier without restricting which days serve, and that adding `start_hour`/`end_hour` restricts serving to those hours (dayparting) — so day-of-week bid modifiers are sent in a form Google Ads accepts.\n- Campaign details now show a keyword's status only when it is not enabled. Enabled keywords omit the status field, paused keywords keep it, and a note explains that a keyword shown without a status is enabled.\n\n## [1.15.10] - 2026-09-14\n\n### Added\n\n- **Added inline (base64) creative uploads to `creative_picker`.** The `upload_creative` action now accepts `file_data` (base64 image bytes, or a `data:` URI) with optional `filename`/`content_type`, writes the bytes to temporary storage server-side, and returns a reusable `upload_ref` for `manage_campaign`. This lets a creative that exists only as a conversation attachment be ingested without the browser upload widget — previously such files produced an `upload_ref` pointing at an empty object, which failed downstream with \"Image download failed\". Inline transport is image/small-file only (capped at 10 MB); video must still use the picker widget, a public `asset_url`, or a pre-uploaded `asset_id`.\n\n## [1.15.9] - 2026-09-14\n\n### Added\n\n- **Data queries now apply a connector's default-on checkbox settings automatically.** When a connector defaults an options checkbox on (for example, Instagram Public Data now skips invalid or restricted handles instead of failing the whole query), queries honour that default without the assistant having to pass the setting. Any value you set explicitly is always respected.\n- **`supermetrics_guide` troubleshooting now covers X / Twitter connectors (X Ads and X Organic) and Google Ads Keyword Planner (GAKEY), and gives clearer help when a just-purchased plan still shows a trial-expired error.** X Organic \"no accounts found\" now explains you must sign in with the X account that owns/administers the handle; GAKEY calls out that it needs Standard (not read-only) Google Ads access; and the license/trial guide now covers the case where a new subscription or trial is in place but `TRIAL_EXPIRED` persists (reconnect so the connector picks up the new license, check it's on the connected team).\n\n## [1.15.8] - 2026-09-14\n\n### Added\n\n- Successful data queries for Microsoft Ads, TikTok Ads, LinkedIn Ads, ChatGPT Ads, and Snapchat Ads now note that campaigns on that platform can also be created, paused, and updated with the manage_campaign tool. The note is skipped when you have managed campaigns on that platform in the last week, and appears at most once per platform per session.\n\n### Changed\n\n- Discovery tools now point the agent at a scope's saved business context when a tag is relevant to what it's doing, and no longer repeat context the agent already fetched earlier in the same session — at team, data-source, and account level. Context too large to show inline is flagged so it isn't silently missed.\n\n## [1.15.4] - 2026-09-11\n\n### Changed\n\n- The deprecated `campaign_create` and `campaign_update` tools are no longer shown in the tool list — use `manage_campaign`, which both creates (omit `campaign_id`) and updates (pass `campaign_id`) campaigns. Existing calls that still use the old tool names continue to work.\n- When `manage_business_context` save text is too long, the error now states the actual length and the per-entry limit and suggests splitting into separate tagged entries, instead of a bare \"maximum length\" message.\n\n### Fixed\n\n- **Corrected the advertised data source count and tool list.** The server instructions and the `llms.txt` / `llms-full.txt` references now state 174 data sources (was \"150+\"/\"170+\") and list the current tools — adding `supermetrics_guide`, `manage_business_context`, `manage_dashboards`, `manage_user_and_team` and `creative_picker`, and surfacing `manage_campaign` — instead of the hidden `user_info` alias.\n- **`data_query`: filters and other parameters placed inside `settings` no longer fail the query.** When a filter expression, date range, `max_rows` or similar query parameter is nested in the `settings` object — a common mistake — it is now moved to where the API expects it instead of being rejected with `SETTING_KEY_INVALID`. Parameters duplicated in both places, and the internal `compress` flag, are dropped rather than passed through.\n\n## [1.15.2] - 2026-09-10\n\n### Changed\n\n- Renamed the creative picker tool from `resources_manage` to `creative_picker`, and made its description clearer that it works with both image and video creatives. The previous name keeps working for existing integrations.\n\n## [1.15.0] - 2026-09-10\n\n### Added\n\n- **Snapchat Ads (SCM) campaign management.** `manage_campaign`, `campaign_and_resource_get` and `data_source_discovery` now support Snapchat Ads. Targeting and optimization are set on each ad squad (ad group) rather than on the campaign, and a `profile_id` on the campaign is required before ads can be created. Budgets are entered as regular amounts (25 for $25), with a $20/day campaign minimum and a $5/day ad squad minimum. Collection, Story, Ad-to-Lens, Reminder and Lead Generation ads each need one extra creative field referencing an id created in Snapchat — see the `manage_campaign` schema for the field names.\n\n## [1.14.19] - 2026-09-10\n\n### Added\n\n- **`campaign_and_resource_get` can now list Google Ads campaign experiments (A/B tests).** Pass `resource_type: \"experiments\"` (or the alias `\"experiment\"`) with a Google Ads `ds_id` and `account_id` to get each experiment's name, status, type, and date range. Previously experiments were only visible in the Google Ads UI.\n\n## [1.14.18] - 2026-09-10\n\n### Changed\n\n- Links to the Supermetrics Hub returned by the tools — for connecting or reconnecting a data source, managing connections, viewing a subscription, tagging accounts, inviting members, or changing campaign settings — now open in the team your session is working in, so the page and any change you make there land in the right team.\n\n## [1.14.17] - 2026-09-09\n\n### Changed\n\n- `manage_business_context` get now matches on any of the tags you pass (OR): `tags: [\"acme,globex\"]` (or `[\"acme\",\"globex\"]`) returns context tagged with either. Useful for fetching context for several clients in one call.\n\n### Fixed\n\n- Team-level business context now appears in `field_discovery` and `accounts_discovery` (and data source config views), not only when listing data sources. Previously a data-source-scoped lookup returned no team rows, so team-wide guidelines could be missed unless you happened to list data sources first.\n\n## [1.14.15] - 2026-09-08\n\n### Added\n\n- **Business context scopes are now advertised in the OAuth protected resource metadata.** The `.well-known/oauth-protected-resource` document now lists `business_context_read` and `business_context_write` in `scopes_supported`, matching the authorization server metadata. OAuth clients discovering the resource server can now request these scopes.\n\n## [1.14.14] - 2026-09-08\n\n### Added\n\n- **A failed campaign approval now shows a support ID.** When applying an approved change does not work, the approval page displays the ID for that request; error responses also carry it as `span_id`, and the `X-Span-Id` response header always has it. Quoting it to Supermetrics support identifies the exact request in our logs; previously a failure gave you nothing to refer to.\n- **Query results now say whether they were answered from the platform's cache, and as of when.** Results carry `cache_used`, plus `cache_time` when a cache answered, and a note naming that time. Ad platforms serve repeat queries from their own result cache — Meta's holds for around 50 minutes — so a read taken shortly after a change can disagree with a live read while both are correct. Previously the response gave no way to tell the two apart. This applies to results returned inline by `data_query` and to those collected with `get_async_query_results`. Where a repeat of an identical `data_query` is served from a stored copy of the earlier run, the response now says so rather than reporting the earlier run's freshness. Both fields are omitted, rather than reported as a live read, when the platform does not tell us.\n\n### Changed\n\n- **Documented `pixel_id` and `promoted_object` on a Meta ad group's `platform_settings`.** Both were already accepted and neither appeared in the schema. `pixel_id` selects which pixel the ad set optimizes for, and `promoted_object` sets what the ad set optimizes towards, as `{pixel_id, custom_event_type}`, `{custom_conversion_id}` or `{page_id}`, which some campaign objectives require. No behaviour changed; these were working before and simply could not be discovered.\n- **The `conversion_types` resource now says that it returns pixels as well as conversion actions.** Pixel details were already in the response on platforms that have them, but nothing in the tool schema mentioned it, so there was no way to find them short of reading a response you had no reason to request. Only the description changed; the data is the same.\n- **`field_discovery` no longer strips a field's description from the cache for later callers.** A wide browse shortens descriptions for its own response; previously it shortened them in the shared catalog, so a later narrow query for the same data source got the shortened copy instead of the full one. Per-data-source description overrides are unaffected either way, and now cannot be shortened at all. The `filter` parameter's description also now mentions that aliases and report types are searched, which they always were.\n\n### Fixed\n\n- **Corrected the documented default for an ad's `status`.** The `status` field said a new ad defaults to PAUSED when omitted. That is not true on every platform — on Meta an ad created without an explicit status can start serving immediately. The description now says the default is the platform's own and may be live, and to set `status: PAUSED` explicitly when an ad must not serve. Nothing about how the field behaves has changed; if you relied on the documented default rather than setting the status, check whether those ads are live.\n- **`campaign_and_resource_get` with `resource_type: videos` now returns videos, not images.** `videos` and `video` resolve to the account's asset library, which holds both and chooses between them by `asset_type` — and the choice fell through to the image default, so a request for videos came back as the image library with nothing in the response saying so. A response whose asset type we inferred — a `videos` request, or a plain `assets` request, which silently meant images — now states which type it served. An explicit `params.asset_type` still wins, so if you have been passing it to work around this, that keeps working unchanged.\n- **`health_check` now states what its click and conversion figures actually count.** On Meta the generic `clicks` field is Clicks (all) — every click on the ad, not only clicks through to your site, which is a separate \"Link clicks\" field — and `conversions` is Actions, a count of every action type rather than one conversion action. The CTR and CPA in a health check are derived from those, so its CTR is CTR (all) and reads higher than link CTR, and its CPA is cost per action. Both figures were correct for what they measured and neither said what that was. Meta health checks now carry a note naming the grain and pointing at `data_query` for link clicks or a specific conversion action. The numbers themselves are unchanged — if you have compared a health-check CTR against link CTR elsewhere and found a gap, this is why.\n- **`resources_manage` now documents the `create_upload_url` action.** The `action` parameter was described as \"Always 'browse_assets'\", so the one action a script needs — create a signed upload URL, PUT your file to it, then pass the returned `upload_ref` to `manage_campaign` as a creative source — could not be found without reading the source. The schema now names it along with the default, and documents the `filename`, `content_type` and `size` inputs it takes. The tool's other actions are unchanged and still accepted; they are driven by the media picker rather than called directly, so they are deliberately left out of the schema.\n\n## [1.14.13] - 2026-09-08\n\n### Added\n\n- **`supermetrics_guide` now offers step-by-step troubleshooting for common problems, so many issues can be solved on the spot instead of waiting on support.** Covered topics: connecting a data source and \"no accounts found\"; connector-specific access for Google (GA4, Search Console, YouTube and more), Meta (Facebook Ads/Insights, Instagram Insights/Public Data), Microsoft (Ads, Bing Webmaster), LinkedIn (Ads vs Company Pages), TikTok (Ads vs Organic), Amazon (Ads/DSP/Seller/Vendor) and data warehouses (BigQuery, Snowflake); reconnecting an expired connection; license and trial errors; adding a data source or destination (e.g. the AI Chats destination) to your plan; adding users or accounts to a subscription (and prioritizing a new account so it's usable); empty query results; numbers that don't match the platform (including GA4 sampling/thresholding); common query errors; quota-exceeded limits; and enabling campaign write access. Just describe the problem (e.g. \"my Google Ads shows no accounts\" or \"why don't my GA4 numbers match?\") and you'll get the relevant steps. The `contact_supermetrics` tool now points to these guides first, so common problems are resolved before a support ticket is created.\n\n### Changed\n\n- `accounts_discovery` now includes an account's saved business context inline (as `context`) when the result is narrowed to a few accounts, so the guidance appears directly instead of requiring a separate lookup. Larger account lists continue to show only `context_tags`.\n\n## [1.14.11] - 2026-09-07\n\n### Added\n\n- New `manage_business_context` tool for storing and retrieving campaign guidelines, policies, and preferences that persist across conversations and are shared with all team members. Context can be saved at team, data source, or account scope, tagged by purpose, and retrieved as a cascade (team + data source + account) so applicable guidelines are applied automatically when creating campaigns, analyzing performance, or building reports.\n\n### Changed\n\n- Discovery tools now surface your team's saved business context in a structured `business_context` property, grouped by scope (`team` and `data_source`) as tags/context entries — or, when a scope holds a lot of context, as a list of tags to load on demand with `manage_business_context`. It's included by `data_source_discovery` (a data source's config, plus team-level context when listing sources), `accounts_discovery`, and `field_discovery`, and the same context isn't repeated once you've already seen it in a session.\n- `accounts_discovery` now lists `context_tags` on an account when your team has saved business context for it, so you can see which accounts have guidelines and load them with `manage_business_context`.\n\n## [1.14.10] - 2026-09-06\n\n### Changed\n\n- **Query results carry fewer, more relevant capability suggestions.** The \"Related capability\" notes attached to a completed query result no longer include the campaign health-check and spend-forecast prompts on every Google, Facebook, LinkedIn or TikTok Ads result. Only the cross-platform comparison suggestion remains — it is still shown only when the paired platform is connected, and it now appears at most once per session instead of on every result.\n\n## [1.14.9] - 2026-09-06\n\n### Fixed\n\n- **`data_query` now accepts a report type given as the index number shown in `field_discovery`'s report type legend.** The index is translated back to the report type name before the query runs, so passing an index (e.g. `report_type: 1`) instead of the name no longer fails.\n\n## [1.14.8] - 2026-09-03\n\n### Changed\n\n- **More data source ID shorthands and typos resolve automatically.** Common guesses are now corrected to the right data source: `SHF` (Shopify), `TT` and `TTA` (TikTok Ads), `SNAPCHAT` (Snapchat Marketing), and `GWT` (Google Search Console).\n\n### Fixed\n\n- **`accounts_discovery` now flags an unknown data source ID instead of offering a dead connection link.** When the data source ID does not exist, the tool points you to `data_source_discovery` to find the correct one, rather than suggesting you connect a source that cannot be connected.\n\n## [1.14.6] - 2026-09-03\n\n### Fixed\n\n- **Meta: an ad set end time sent with a time but no timezone offset no longer lands a day late.** A value like `2026-11-20T23:59:00` was passed to Meta unanchored, which resolved it in its own timezone — an end-of-day time then crossed midnight and moved the date to the 21st. Such values are now anchored to the ad account's timezone, matching the behaviour already applied to campaign dates. A value that carries an explicit offset is still used exactly as sent. If you have been compensating by sending a date one day early, that adjustment is no longer needed.\n- **Meta: an ad set's start and end date can now be changed after it is created.** Set `start_date` / `end_date` in an ad group's `platform_settings` — Meta holds the flight on the ad set, so a campaign-level date never reached one that already existed. Previously each route failed differently: a campaign-level date reported the write as applied and changed nothing, and a date on the ad group was either reported as an unrecognized field or passed to Meta and silently dropped. A campaign-level date on an update now also says that ad sets keep their own flight, instead of reporting success over an unchanged value.\n\n## [1.14.5] - 2026-09-03\n\n### Fixed\n\n- **Approvals blocked by a data source connection now say so, and link you straight to reconnecting it.**\n  A change that could not be applied because the connection was missing permissions or had expired used to\n  report a server error and suggest trying again, which never worked. The approval page now explains that\n  the connection needs reauthorising and shows the reconnect address as a link you can click.\n\n## [1.14.3] - 2026-09-03\n\n### Changed\n\n- **The `campaign_and_resource_get` conversions resource is now called `conversion_types`, making clear it lists the account's configured conversion actions (definitions), not per-campaign conversion counts.** The previous `conversions` name continues to work unchanged.\n\n### Fixed\n\n- **`campaign_and_resource_get` now gives targeted guidance when `campaign_id` is passed to a resource that cannot filter by it, instead of always saying \"fetch a single campaign\".** Asking `conversion_types` for a campaign's conversion numbers now points to the `data_query` tool, and asking `assets` for a campaign's creatives now points to fetching that campaign with full detail.\n\n## [1.14.2] - 2026-09-02\n\n### Fixed\n\n- **`data_query` no longer fails with \"Missing value for query start date\" when the date range is placed inside `settings`.** A date range provided as `date_range_type`, `start_date`/`end_date`, or `date_range` inside the `settings` object — rather than as a top-level parameter — is now applied to the query instead of being ignored.\n- Published pages and other clients that invoke `campaign_create` or `campaign_update` by name from a declared tool manifest work again. The two legacy names are listed as deprecated aliases of `manage_campaign` (they had briefly stopped appearing in the tool list after the tools were merged). Prefer `manage_campaign` — the aliases forward to it with identical parameters.\n\n## [1.14.0] - 2026-09-02\n\n### Changed\n\n- Campaign creation and updates are now performed through a single `manage_campaign` tool: provide `campaign_id` to update an existing campaign, or omit it to create a new one. The previous `campaign_create` and `campaign_update` names continue to work unchanged.\n\n### Fixed\n\n- `campaign_create` and `campaign_update` now say plainly that a platform has no campaign management, instead of returning a write-access error that pointed to a settings page where the platform could never be enabled.\n\n## [1.13.3] - 2026-09-01\n\n### Changed\n\n- The `max_rows` parameter for `data_query` no longer documents a fixed 10,000-row maximum. There is no such hard ceiling; the default remains 1000 and any upper limit depends on your license.\n- `accounts_discovery` now names the team you are currently working in and explains that the accounts it lists belong to that team — a connection added while signed in to a different team will not appear here — and its link for adding more connections opens that same team, so a new connection lands where your queries can find it.\n\n## [1.13.2] - 2026-08-31\n\n### Fixed\n\n- **Asset picker: creatives you generate or upload during a session no longer disappear when the picker is reopened or the page is reloaded.** The picker now refreshes \"Your assets\" from the server on load, so a freshly generated AI image or uploaded file stays visible instead of dropping off on the next render.\n\n## [1.13.1] - 2026-08-31\n\n### Fixed\n\n- **Asset picker: AI-generated creative thumbnails now keep loading, and deletions stick.** Previously, AI-generated images in the media picker's \"Your assets\" showed a blank thumbnail and could vanish when the picker was reopened, and deleting your last asset(s) could make them reappear on reload. Both are resolved — AI creatives now preview reliably alongside your uploads, and a deleted asset stays gone.\n\n## [1.12.13] - 2026-08-31\n\n### Added\n\n- `data_source_discovery` now tells you, when you fetch a specific ad platform's configuration, which read operations that platform exposes through the `campaign_and_resource_get` tool — such as keyword ideas, keyword volumes, forecasts, targeting search, and audiences — so you can reach for the right tool instead of attempting a `data_query` that cannot return them.\n\n## [1.12.11] - 2026-08-28\n\n### Added\n\n- **Connect suggestions on query results** — a completed query against Google Ads, Facebook Ads, Google Analytics or Google Search Console may now note one related data source you have not connected and what it would add that the source you queried cannot answer on its own. Only sources you genuinely do not have are named, at most one per query, and each is mentioned once and not raised again.\n\n### Changed\n\n- `data_query` now returns your rows directly when the query finishes quickly, instead of always handing back an ID to fetch them with. Combined with the change below, a short report can arrive in a single call rather than three. Rolling out gradually.\n- `get_async_query_results` now waits for your query to finish instead of reporting it as still running after a couple of seconds. Most queries return their data on the first call, so retrieving a report no longer costs several rounds of asking and waiting. Rolling out gradually.\n\n### Fixed\n\n- A query could be reported as still queued, with out-of-date progress, after it had already started running.\n- A query that failed could return a generic message instead of the error explaining what actually went wrong.\n- A campaign health check whose query ran long took about twice as long as it needed to before reporting the problem.\n\n## [1.12.7] - 2026-08-27\n\n### Fixed\n\n- Campaign management: Google Ads Shopping ad groups now honour a `product_filter` set in their own `ad_groups[]` entry. It was accepted and never applied, and because a bid sent alongside it did apply, the response reported the write as successful — leaving the ad group serving no products. Previously only Performance Max asset groups supported a per-group filter.\n- Campaign management: a `product_filter` that cannot be applied — an unsupported campaign type, an ad group that cannot be identified, or one belonging to a different campaign — is now reported in `failures` with `dropped: [\"product_filter\"]` rather than only mentioned in `notes`, so it is no longer reported as an applied write.\n\n### Changed\n\n- Campaign management: the `campaign_update` `platform_settings.product_filter` description now points at the per-ad-group alternative, since the campaign-level filter rebuilds every group in the campaign.\n\n## [1.12.6] - 2026-08-26\n\n### Changed\n\n- `data_source_discovery` now recognizes common alternative names when filtering, so searches like \"GA4\", \"Google Business Profile\", \"DV360\", \"AdWords\", \"Microsoft Ads\", \"Magento\", or \"Facebook Page\" resolve to the right data source instead of returning nothing.\n\n## [1.12.5] - 2026-08-25\n\n### Added\n\n- `campaign_update` ads now accept a top-level `status` field (ENABLED, PAUSED, or REMOVED) instead of requiring it inside `platform_settings`.\n\n### Fixed\n\n- Google Ads: updating an ad's creative no longer silently pauses the ad. Google Ads has no in-place creative update, so the ad is removed and recreated under a new ID — its status is now carried over from the ad being replaced. If the prior status can't be confirmed, the update now stops with an explanation rather than risking an unintended pause; pass `status` explicitly to proceed anyway.\n\n## [1.12.3] - 2026-08-24\n\n### Fixed\n\n- `get_async_query_results` now returns an empty `data: []` for a completed query that produced no rows, instead of a single sentinel row `[[\"No data found\"]]`. Empty results are now a consistent shape regardless of which data source or report type produced them.\n\n## [1.12.0] - 2026-08-20\n\n### Added\n\n- Clients speaking MCP `2026-07-28` are now served directly instead of being turned away and having to fall back to an older protocol version. Change notifications are not part of that support: the server does not push tool, prompt, or resource updates and does not accept a subscription stream, so re-read the tool list whenever you need it to be current.\n\n### Fixed\n\n- A conversation that moves between servers mid-session now keeps the capabilities your client declared when it connected, instead of being treated as though it had declared none.\n- A request whose body is not valid JSON now answers `400 Bad Request` with a parse error naming where it failed, instead of reporting a `500` server error.\n- Calling a method the server does not have now answers \"Method not found\" and names the method, instead of the misleading \"Invalid request parameters\".\n\n### Changed\n\n- `serverInfo.version` in the initialize response now reports the Supermetrics MCP server's own version rather than the version of the MCP library it is built on.\n\n## [1.11.9] - 2026-08-20\n\n### Added\n\n- Campaign create and update responses now say whether the platform actually applied the change. `write_status` is `applied`, `partial_failure` or `failed`, and `failures` lists each change the platform refused, with its error code where the platform gives one. Previously a partly-refused write looked like a success and the reason appeared only as a note, so there was no reliable way to tell how much of a request had gone through. `notes` still carries advisories, and any refusal a connector cannot report in `failures`.\n\n## [1.11.8] - 2026-08-19\n\n### Changed\n\n- Tool responses no longer include `trace_id` in their metadata. Responses continue to carry a `span_id`; on a failed request, this is the ID to quote when contacting Supermetrics support.\n\n### Fixed\n\n- A data query that fails because the connection behind the account is no longer usable now says what to do about it. Previously it returned only the bare message `Query authentication \"<id>\" is no longer available.` — an id that appears nowhere in the product, with no reconnect link. It now comes with a link to reconnect the data source, and, for the case where you have already reconnected and nothing changed, a pointer to `accounts_discovery`: reconnecting under a different login creates a new connection rather than restoring the one the account was being queried through.\n\n- Query errors no longer repeat the same guidance twice. A missing date range, or a missing/mismatched per-query setting, now returns a single `SOLUTION` hint. For missing settings, that hint names the exact `setting_id` values by their identifier (not just the human-readable label), and lists only the settings required for the report type being queried.\n\n## [1.11.6] - 2026-08-18\n\n### Fixed\n\n- Ending a session that has already expired now answers `404 Not Found` with a readable JSON error, instead of reporting success for a session that was no longer there. Ending a live session is unchanged.\n- Ending a session with a malformed session id now answers with a JSON error too. It previously returned unlabelled plain text, which some clients could only report as invalid content from the server.\n\n## [1.11.4] - 2026-08-18\n\n### Changed\n\n- `contact_supermetrics` now checks your existing open tickets before creating a new support ticket, and adds to a matching open ticket instead of opening a duplicate.\n\n## [1.11.2] - 2026-08-17\n\n### Added\n\n- `contact_supermetrics` can now check on your existing support tickets: list your tickets (each with a link to view it), read the replies on one, and post a follow-up — all limited to tickets you opened. Use `type: \"ticket_status\"` (optionally with a `ticket_id`) to view, and `type: \"ticket_reply\"` with a `ticket_id` and `message` to respond.\n\n## [1.11.1] - 2026-08-17\n\n### Fixed\n\n- Uploading a creative from a web page URL now works: when the URL points at a page rather than a direct image file, the asset picker automatically uses the page's preview image (`og:image`) instead of failing with \"URL returned a web page, not an image.\"\n\n### Changed\n\n- When AI image generation isn't available on your plan, the asset picker now returns a clear message explaining an active license is required and suggesting you browse or upload an existing image, instead of surfacing a generic error.\n\n## [1.11.0] - 2026-08-16\n\n### Fixed\n\n- A conversation whose session had expired could keep failing against it — often surfacing as a tool call that suddenly errored after working for hours, with only disconnecting and reconnecting the connector fixing it. The server now tells the client to start a fresh session, so it reconnects on its own.\n\n## [1.10.16] - 2026-08-15\n\n### Fixed\n\n- Media picker asset thumbnails and previews now load in Claude across all production environments. The 1.10.15 fix restored the image request URL but did not yet allow that origin, so images stayed blocked in some deployments.\n\n## [1.10.15] - 2026-08-15\n\n### Fixed\n\n- The media picker (opened by `resources_manage`) again shows asset thumbnails and image previews, and file uploads work again. Both had silently stopped loading in Claude.\n\n## [1.10.14] - 2026-08-14\n\n### Fixed\n\n- The asset picker (`resources_manage`) no longer intermittently fails to open. Opening calls that carried an explicit `null` or empty `action` are now treated as the default `browse_assets` instead of being rejected.\n- `field_discovery` no longer fails for a whole data source when its field catalog contains an unusual field definition (seen with some Klaviyo custom-event metrics). Fields are now returned even if an individual field can't be read, instead of the entire source becoming unusable.\n\n## [1.10.11] - 2026-08-14\n\n### Added\n\n- Every response now includes a \"span ID\" identifier for that individual request. Quoting it when reporting a problem lets support pinpoint the exact request that went wrong, rather than narrowing it down from everything else that happened in the same conversation.\n\n## [1.10.9] - 2026-08-14\n\n### Added\n\n- Feature requests can now be submitted and voted on at the public wishlist (https://wishlist.supermetrics.com). The `contact_supermetrics` tool points users there for feature ideas, offering it as an alternative when they share feedback.\n\n## [1.10.3] - 2026-08-12\n\n### Removed\n\n- `accounts_discovery` no longer accepts `include_connection_details`, introduced in 1.10.1. Accounts are returned as a single list again, without the connection grouping.\n\n## [1.10.2] - 2026-08-12\n\n### Changed\n\n- Requests larger than 45 MB are now rejected.\n\n## [1.10.1] - 2026-08-11\n\n### Added\n\n- `accounts_discovery` can now return accounts grouped by the connection they come through, with each account carrying its data source username. Enable it with `include_connection_details`; it is off by default, and the normal account list is unchanged.\n- Completed query results for Facebook Ads, Google Ads, LinkedIn Ads and TikTok Ads now carry short notes about related capabilities that apply to that platform — the campaign health check, spend forecasting, and comparing against a second ad platform — each with a phrase you can say to try it. A cross-platform note only appears when the other platform is already connected, so it never points at a source you cannot query.\n\n### Changed\n\n- `supermetrics_guide` is now surfaced at the moments it actually helps: an opening question like \"what can you do?\", a request the connector cannot fulfil (where the guide can point to an alternative), or a natural pause after several queries against one source. It stays out of the way while a specific question is being answered or a query is being drilled into, and related capabilities mentioned in query result notes are offered as one follow-up option among others rather than pushed.\n\n## [1.10.0] - 2026-08-10\n\n### Fixed\n\n- MCP clients can now close a session when they disconnect. The server previously refused the request, so the session stayed open until it timed out.\n\n## [1.9.42] - 2026-08-10\n\n### Fixed\n\n- `accounts_discovery` no longer fails with \"Could not resolve team ID from user identity\" when the Supermetrics sign-in has expired. The tool now reports the expired sign-in so the client can refresh it and retry, instead of reporting a team problem that has nothing to do with the actual cause. It also recovers on its own in cases where it previously gave up without trying.\n\n## [1.9.41] - 2026-08-07\n\n### Added\n\n- New `supermetrics_guide` tool answers \"what can I do with Supermetrics?\" and \"what's new?\" with a short, numbered list of capabilities, each with the exact phrase to try on its own line so it is easy to spot and copy. Previously there was no way to find out what the connector supports from inside a conversation, so features went unnoticed unless a user happened to ask for them by name.\n\n### Changed\n\n- Reverted the 1.9.38 change that returned an error for a query reported as stalled after it had completed. It also affected queries that re-run on a schedule, reporting a failure for them while they were simply running normally. These queries now behave as they did before 1.9.38.\n\n## [1.9.38] - 2026-08-06\n\n### Fixed\n\n- Queries that stall after completing no longer leave results loading indefinitely. `get_async_query_results` now returns a clear error for such a query so it can be re-run, instead of reporting it as still running forever.\n\n## [1.9.35] - 2026-08-05\n\n### Fixed\n\n- `contact_supermetrics`: support tickets are now created reliably and return a working ticket link. Previously a ticket could report success with an invalid link ending in `/None` while not actually reaching Supermetrics support; the tool now confirms the ticket was created and returns a clear error if it was not.\n- `contact_supermetrics`: support tickets submitted without a category are no longer rejected. A general category is now applied automatically when none is provided, so the ticket is accepted instead of failing.\n\n## [1.9.33] - 2026-08-03\n\n### Added\n\n- Campaign management: Google Ads Performance Max asset groups accept their own `product_filter` in an `ad_groups[]` entry's `platform_settings`, applied to that asset group alone. Previously the only option was the campaign-level filter, which rebuilds the listing groups of every asset group in the campaign — unusable for changing one group in a campaign that has many.\n- Campaign management: the accepted Performance Max image aspect ratios (1.91:1, 1:1, 4:5) are now stated in the `assets` description, so an image can be corrected before it is submitted rather than after Google rejects it.\n\n### Fixed\n\n- Campaign management: `status` on an ad group / asset group entry is now honoured when creating Google Ads Performance Max asset groups. Previously the requested status was discarded and the asset group was always created ENABLED, so an asset group added to a live campaign began serving immediately despite an explicit `PAUSED` request.\n- Campaign management: new Performance Max asset groups in a Merchant Center-linked campaign now get an all-products listing group when no `product_filter` is given. Previously they were created with no listing group at all, so they served no products while reporting success.\n- Campaign management: warnings returned by the campaign API now appear in the response's top-level `notes`. Previously they were nested one level deeper and easy to miss.\n\n### Changed\n\n- Campaign management: `status` is now a documented field on ad group / asset group entries. New Performance Max asset groups default to PAUSED unless a status is given, and the guidance now requires explicit user approval before an ad group or asset group is enabled — previously the approval step covered campaigns only.\n- Campaign management: the campaign-level `product_filter` description now states that it rebuilds the listing groups of every ad group in the campaign, and the guidance on omitting it for all products now matches actual behaviour.\n\n## [1.9.32] - 2026-07-29\n\n### Fixed\n\n- `field_discovery` no longer returns an empty field list when `filter` terms are separated by spaces instead of commas (e.g. `impressions clicks spend`). Previously such a filter matched nothing, which could leave an assistant unable to name any fields for a query. Multi-word terms that match a field name (e.g. `impression share`) still match as a phrase.\n\n### Changed\n\n- The `field_discovery` `filter` parameter description now states that terms are comma-separated.\n\n## [1.9.31] - 2026-07-28\n\n### Added\n\n- Campaign management: Google Ads (AW) now supports radius/proximity targeting. Use `location_details` with `type=custom_location`, `latitude`, `longitude`, `radius`, and `distance_unit` (mile or kilometer) to target people within a radius of a point. Works for local service campaigns.\n- Campaign management: Google Business Profile locations can now be linked to Google Ads campaigns via `extensions.locations` with a `place_id`. Requires the GBP to be linked to the Google Ads account first.\n\n## [1.9.29] - 2026-07-27\n\n### Added\n\n- Campaign management: Google Ads (AW) now supports city-level geo targeting. Pass numeric geo target constant IDs in `locations` (e.g. `[\"DE\", \"1001062\"]`) or use `location_details` with city/region entries. Use targeting search with `type=city` or `type=location` to discover geo IDs by name.\n- Campaign management: Google Ads `geo_target_type` setting — set `PRESENCE` in platform_settings to target people physically present in the location (default: `PRESENCE_OR_INTEREST`).\n\n## [1.9.25] - 2026-07-21\n\n### Added\n\n- `field_discovery` now marks non-aggregatable metrics (e.g. Reach, Frequency, Users, and rate/ratio metrics like CTR, CPC, ROAS) with `is_non_aggregatable: true`, and adds a note clarifying that these metrics can still be broken down by dimensions or dates within a single query, but their returned values must not be summed or averaged across rows afterward. Previously these metrics were returned with no such indication, so summing them (for example, adding daily Reach into a weekly total) silently produced inflated, double-counted figures.\n\n## [1.9.23] - 2026-07-21\n\n### Fixed\n\n- Publishing a dashboard to Supermetrics Studio now warns when the uploaded board contains no live `smQuery` calls. Previously a static, data-baked-in board could be published silently and would never refresh — leaving viewers to reconnect every source by hand. The upload response now flags this so the board can be rebuilt with live queries and re-uploaded.\n- Campaign management: end dates no longer shift +1 day for ad accounts in timezones east of UTC. Previously, setting `end_date=2026-09-30` could display as October 1st in Meta Ads Manager.\n\n### Added\n\n- Campaign management: `start_date` and `end_date` now accept an optional time-of-day in ISO 8601 format (e.g. `2026-09-30T18:00:00`), in addition to the existing date-only format (`YYYY-MM-DD`). This lets you schedule campaigns to start or stop at a specific hour.\n\n## [1.9.22] - 2026-07-21\n\n### Added\n\n- Campaign management: saved audiences are now included when listing audiences (`type=saved`). Previously only custom/remarketing/lookalike audiences were returned.\n- Campaign management: geo-location search is now available via targeting search. Use `type=city`, `type=region`, `type=country`, `type=zip`, `type=geo_market`, or `type=location` (all types) to find Meta geo keys for sub-country targeting in `location_details`.\n\n## [1.9.21] - 2026-07-20\n\n### Changed\n\n- Campaign management: `destination_type` documentation now covers all objectives (WEBSITE, ON_AD, APP, etc.), not just messaging ads. Helps avoid trial-and-error when setting conversion location for non-messaging campaigns.\n- Campaign management: `platforms` field now lists valid Meta publisher platforms (facebook, instagram, audience_network, messenger). `placements` field documents cross-platform shortcuts (feed, reels).\n- Campaign management: creative asset documentation reordered to highlight `asset_url` (public URL) as the recommended path for uploading new media. Both `campaign_create` and `campaign_update` tool descriptions now mention available creative options.\n\n## [1.9.20] - 2026-07-17\n\n### Changed\n\n- Dashboards built for Supermetrics Studio now come with more flexible dates and period comparison. Date pickers offer a wider set of ranges — including last 90 days and other multi-day/week/month/year windows — plus fully custom start/end dates and derived ranges like this/last quarter and year to date. When you want to compare performance, dashboards can now apply a single comparison — previous period or the same period last year — consistently across every widget, including time-series charts, not just individual scorecards.\n\n## [1.9.19] - 2026-07-17\n\n### Removed\n\n- Reverted the \"Query stalled\" detection for async queries (introduced in 1.9.16 and refined in 1.9.18). `get_async_query_results` no longer marks a query as stalled based on it running without scheduled work — that signal proved unreliable for some data sources (for example Adobe Analytics), which can run in that state for several minutes and still complete, so healthy queries were being failed. Such queries now continue polling until they finish, as they did before 1.9.16.\n\n## [1.9.18] - 2026-07-16\n\n### Fixed\n\n- `get_async_query_results` no longer fails a query with a \"Query stalled\" error just because it is briefly reported as running without any work scheduled yet — a normal state in the first seconds after a query is submitted. A query is now only reported as stalled if it stays in that state for a sustained period across polls, so newly submitted queries that simply need a moment to start are allowed to finish. This removes spurious stall errors (and empty dashboard tiles) that could appear for queries that would otherwise complete normally.\n\n## [1.9.17] - 2026-07-16\n\n### Added\n\n- After a dashboard is published to Supermetrics Studio, the assistant now invites you to share feedback on your overall Studio experience (once per session, non-blocking, and skippable). If you share feedback, it is delivered to the Supermetrics team.\n\n## [1.9.16] - 2026-07-14\n\n### Fixed\n\n- `get_async_query_results` no longer polls forever on a query that has stalled. When a query is reported as running but has no work actually scheduled or running — a state it can never recover from on its own — it is now returned as a failed query instead of an endless \"keep polling\" response. The stalled query's cached schedule is cleared, so re-running it (or reloading the page) submits a fresh query that completes normally. Previously such a query could stall indefinitely and repeated attempts kept reusing the same stuck query for up to ~53 minutes.\n\n## [1.9.15] - 2026-07-09\n\n### Fixed\n\n- Query results are no longer automatically compressed. Compression now only applies when you explicitly pass `compress=true`. Previously, results were sometimes returned in a compact text format even when raw data was requested, which broke integrations that expected standard JSON arrays.\n\n## [1.9.13] - 2026-07-09\n\n### Fixed\n\n- `manage_dashboards` `upload`/`edit`: when Supermetrics Studio rejects a dashboard for invalid code (for example, the same top-level function declared twice, or truncated/unparseable code), the error now shows Studio's full, actionable message — which problem it is, where it is, and how to fix it — instead of a generic, truncated \"HTTP 422\" response. This lets the dashboard be corrected and re-uploaded without guesswork.\n\n## [1.9.11] - 2026-07-09\n\n### Fixed\n\n- Large query results (over 10,000 rows) no longer crash the server. Results above 10K rows are automatically compressed and skip the result cache to stay within memory limits. Previously, very large results (e.g. a full product catalog) could cause a server crash with no actionable error message.\n\n## [1.9.10] - 2026-07-09\n\n### Fixed\n\n- `manage_dashboards` `upload`: uploading no longer fails when the `title` is missing or blank. A title is now derived from the dashboard code — its `<title>`, otherwise the first heading, otherwise \"Untitled dashboard\" — so the board is created instead of the whole upload being rejected. Set `title` explicitly to control the display name.\n\n## [1.9.9] - 2026-07-08\n\n### Fixed\n\n- `manage_dashboards` `upload`: uploading now rejects a `code` value that is a file path (e.g. `/home/claude/board.html`) or other non-dashboard text before the board is created, with an actionable error telling you to pass the file's contents instead. Previously such a value was stored verbatim, so the shared Studio link showed the literal path text instead of a rendered dashboard.\n\n## [1.9.7] - 2026-07-07\n\n### Added\n\n- `manage_dashboards` `upload`: you can now set an optional `description` (a short subtitle/summary of the dashboard, up to 2000 chars) when uploading. It is stored on the board and shown in the board list, and is returned by `get`. Previously only the title, code, and access settings could be set.\n\n### Fixed\n\n- Campaign approval errors now show the actual rejection reason from the ad platform instead of a generic \"HTTP 502\" error\n\n## [1.9.6] - 2026-07-07\n\n### Fixed\n\n- `manage_dashboards`: after building a dashboard, the assistant now always offers to publish it to Supermetrics Studio for a shareable, always-fresh link, instead of just showing the in-chat preview and stopping. The upload still happens only after you confirm — this just makes sure you're always told the option exists.\n\n## [1.9.5] - 2026-07-07\n\n### Added\n\n- `manage_dashboards` `upload`: the response now includes a `code_warnings` list when an uploaded board looks likely to render empty — specifically when it queries Supermetrics data but never maps columns via `result.data.requested_field_ids`. The warning names the fix so the board can be corrected and re-uploaded before sharing, instead of the data-wiring problem only surfacing when someone opens the board. Advisory and non-blocking: the upload still succeeds.\n\n### Fixed\n\n- `manage_dashboards`: the in-chat preview shown before uploading is now a static page with your real data baked in, so it actually renders here instead of coming up empty. Previously the preview reused the live Studio version (which fetches data through a Studio-only helper), so it showed no data and came with a confusing \"won't pull data outside Studio\" note. The version uploaded to Supermetrics Studio is still the live, always-fresh one.\n\n## [1.9.4] - 2026-07-07\n\n### Fixed\n\n- `manage_dashboards` `upload`: a dashboard is now shown to you in the chat first and you're asked before it's published to Supermetrics Studio as a shareable link, instead of being uploaded and shared unprompted. If you explicitly ask to publish or share it to Studio (e.g. \"put this in Studio and give me a share link\"), it still uploads right away.\n\n## [1.9.3] - 2026-07-06\n\n### Fixed\n\n- `manage_dashboards` `upload`: dashboards you generate now render their data on the first view instead of frequently coming up empty until fixed in the Studio editor. The `code` guidance now documents the exact shape `smQuery` returns (data is a 2D array at `result.data.data` — row 0 headers, rows 1+ data — with columns mapped by `result.data.requested_field_ids`, not the display labels), so the generated board code parses query results correctly out of the box.\n\n## [1.9.2] - 2026-07-06\n\n### Changed\n\n- `manage_dashboards` `edit`: region-replace patches (`from`/`to`) now replace the whole region **including** the anchor marker lines, matching the Supermetrics Studio edit AI. Write the complete new block in `replace` and reproduce the `from`/`to` marker lines inside it (the server forces this behavior, so a restated anchor no longer duplicates a declaration). Requires the paired dazl-backend change that adds `include_anchors` support.\n\n## [1.8.4] - 2026-07-03\n\n### Changed\n\n- `manage_dashboards` `upload` and `get` responses now omit the board review-status fields unless the board has been blocked by content review — in which case the status and reason are included so you can surface a remediation notice. Previously these fields were always returned, even for the benign default state.\n\n## [1.8.3] - 2026-07-03\n\n### Changed\n\n- `manage_dashboards` `upload` no longer echoes back the dashboard code you just submitted — the response now returns only the dashboard metadata (id, title, view URL). Use the `get` action to retrieve the stored code when you need it.\n\n## [1.8.1] - 2026-07-03\n\n### Added\n\n- TikTok Ads (TIK) REACH campaigns now support frequency cap settings. Set `frequency` (max impressions per user) and `frequency_schedule` (period in days) in ad group `platform_settings`. Previously these fields were silently dropped, blocking all REACH campaign creation.\n- TikTok Ads (TIK) ad groups now support additional `optimization_goal` values (`ENGAGED_VIEW`, `CONVERSION`, `INSTALL`) and the `CPV` `billing_event`.\n- TikTok Ads (TIK) campaigns now support Campaign Budget Optimization (CBO). Set `budget_optimize_switch: \"ON\"` in campaign `platform_settings` to manage budget at the campaign level — ad groups no longer require their own budget when CBO is enabled.\n- TikTok Ads (TIK) placement type is now auto-detected: when `placements` are specified (in targeting or platform_settings), `placement_type` is automatically set to `PLACEMENT_TYPE_NORMAL`. This fixes VIDEO_VIEWS campaigns that previously failed with \"This ad objective only supports manual placement.\"\n\n### Fixed\n\n- TikTok Ads (TIK) campaign read-back now includes `budget_type` (DAILY/LIFETIME) on ad groups when the data is available from TikTok's API.\n\n## [1.8.0] - 2026-07-02\n\n### Fixed\n\n- Meta Ads (FA) ad set creation no longer fails with \"you need to enable or disable the Advantage audience feature.\" Advantage+ Audience now defaults to disabled when not specified — your targeting is applied as-is. Set `advantage_audience` to `true` in targeting to let Meta expand beyond your specified audience. Both the flat key and Meta's nested `targeting_automation.advantage_audience` format are accepted.\n\n## [1.7.0] - 2026-07-02\n\n### Added\n\n- New `manage_dashboards` tool: upload dashboards to Supermetrics Studio. Studio dashboards have live data and refresh without spending tokens (unlike dashboards in Claude) and can be shared with anyone.\n\n## [1.6.2] - 2026-07-02\n\n### Added\n\n- PMax asset group UPDATE: you can now update an existing Performance Max asset group by providing its ID. Headlines, descriptions, images, and other assets are replaced in-place instead of requiring a new asset group. Set `ad_groups[].id` to the existing asset group ID.\n- Warnings for silent transformations: the `notes` array now reports when portrait images (4:5 ratio) may not appear on all PMax surfaces, and confirms when search themes are applied as optimization signals.\n\n### Changed\n\n- The `campaign_update` tool description now documents the extensions payload schema (callouts, sitelinks, structured snippets) including field names and required formats.\n- Sitelinks now accept both `text` and `link_text` as the display text field name, for compatibility with Google Ads API conventions.\n- Structured snippet `header` field description now lists all valid English enum values.\n\n## [1.6.1] - 2026-06-30\n\n### Changed\n\n- The campaign change-approval page now shows the full proposed change — campaign fields, plus a card per ad group and ad with each changed field (headline, primary text, CTA, final URL, page, image) shown as old → new on edits — instead of collapsed lines like \"Ad groups updated\".\n\n## [1.6.0] - 2026-06-29\n\n### Added\n\n- Campaign changes that go live — enabling a campaign, or editing a campaign that is already live — can now require your explicit approval. When approval is required, the response includes a secure approval link; opening it shows a summary of the change and applies it only after you click Approve. Validation errors are surfaced first, so you only ever approve a change that is ready to apply. If applying the approved change fails, the page shows the specific reason; if it applies with caveats (for example, an ad pending platform review), those notes are shown too. The link works in any client.\n\n## [1.5.18] - 2026-06-28\n\n### Fixed\n\n- **Connecting an unconnected data source now gives clear next steps** — when `accounts_discovery` finds no connected account for a data source, the response already includes a connection link. Previously the appended guidance also told the assistant to call `accounts_discovery` again (the tool that just reported the problem), which could cause it to loop instead of helping the user connect. The guidance now tells the assistant to share the connection link with the user so they can connect the data source, then retry.\n\n## [1.5.17] - 2026-06-28\n\n### Fixed\n\n- **`accounts_discovery` no longer shows a connection link for connectors that don't use an account list** — some data sources (e.g. free-text connectors) have no account list to browse, and some require no connection at all. Calling `accounts_discovery` for those used to return a misleading \"connect this data source\" login link. It now returns clear guidance computed from the connector: whether an account is supplied as a free-text identifier in `ds_accounts`, and a connection link only when the data source actually needs to be connected. For no-auth data sources, the connection is set up automatically so accounts can be listed without a login step.\n\n## [1.5.16] - 2026-06-26\n\n### Fixed\n\n- **Runtime connector errors are no longer mislabelled as an invalid data source** — when a query against a valid connector failed at runtime with a message like \"Data Source Error: Not Found\" (seen with Google BigQuery), `get_async_query_results` would wrongly append \"Did you mean …?\" suggestions and tell you to pick a different data source. The original connector error is now returned unchanged, without the misleading data-source suggestion.\n\n## [1.5.15] - 2026-06-25\n\n### Fixed\n\n- **Meta Ads (FA) campaign tools now accept ad-account IDs with or without the `act_` prefix** — campaign tools (list, create, update, status, assets, forecast, audiences, conversions, …) no longer fail with \"Connection expired\" when an `account_id` is supplied without the `act_` prefix. Both `1234567890` and `act_1234567890` now work.\n\n## [1.5.14] - 2026-06-25\n\n### Added\n\n- **Add or remove keywords on an ad group (Google Ads & Microsoft Advertising)** — `campaign_create` and `campaign_update` now accept `add_keywords` and `remove_keywords` on an ad group. `add_keywords` appends positive keywords (skipping duplicates) without touching the ad group's other targeting; `remove_keywords` deletes matching keywords. Use these for incremental keyword edits — `targeting.keywords` still replaces the whole set.\n\n### Fixed\n\n- **`campaign_update` no longer silently does nothing when keywords are passed at the top level** — previously, calling `campaign_update` with keywords (e.g. under an invented `action` argument) instead of nesting them under an ad group returned success while changing nothing. Such keywords are now routed to the intended ad group when it's unambiguous (an `ad_group_id` or a single ad group is given), and otherwise return a clear error explaining the correct shape.\n\n## [1.5.13] - 2026-06-25\n\n### Added\n\n- **Sub-country location targeting for Meta Ads campaigns** — `campaign_create`, `campaign_update`, and forecast/reach-estimate tools now accept `location_details` in `targeting` for city, region, ZIP, geo-market, and custom-location targeting. Use `targeting_search` to look up Meta geo keys.\n- **Facebook Ads carousel, video, and boosted-post creatives** — `campaign_create` and `campaign_update` now expose `carousel_cards`, `object_story_id`, and `asset_type` on ad creatives, making it possible to create carousel ads (2–10 cards), boost existing Page/Instagram posts by ID, and explicitly mark uploaded media as video.\n\n## [1.5.11] - 2026-06-24\n\n### Fixed\n\n- **`campaign_update` tool guidance** — tool and parameter descriptions now explain that `campaign_update` is also used to create new ad groups/ads inside an existing campaign, and that operations are inferred from the presence/absence of `id` fields (there is no `update_type` parameter).\n\n## [1.5.10] - 2026-06-18\n\n### Added\n\n- `user_info` now reports license warnings (such as an expired credit card) in the license details on every call.\n- When your account has a license warning like an expired credit card, the warning — including a link to update your card — is now surfaced as a note once per session, on the first tool you use.\n\n## [1.5.9] - 2026-06-16\n\n### Added\n\n- **AI-generated logos in campaign creatives** — `campaign_create` and `campaign_update` now accept `logo_prompt` on ad creatives, generating the logo from a text prompt. Combined with `asset_prompt`, visuals can be supplied end-to-end without opening the media picker.\n\n### Changed\n\n- **Clearer error when uploading local files** — passing a local file path or unsupported URL scheme to image upload or the image proxy now returns a specific message explaining the issue, instead of the generic \"Only HTTPS URLs are supported\".\n\n## [1.5.8] - 2026-06-15\n\n### Changed\n\n- **Leaner tool responses** — presentation fields (`title`, `subtitle`, `source_url`) are now included only for clients that render them as cards (Microsoft Copilot). All other clients receive smaller responses without these fields, reducing token usage.\n- **Null `error` omitted** — tool responses no longer include the `error` field when it is null; it appears only on actual failures.\n- **`get_async_query_results`** — the redundant `message` field is dropped from polling responses (`polling_instruction` already explains how to poll), and the tool description now clarifies that result rows are in `data.data` (the inner `data` field), not directly in the top-level `data`.\n- **Currency recommendation** — when a query returns monetary values without a currency dimension, the recommendation is now more concise and names the specific currency field IDs available for that data source so you know exactly what to add.\n\n### Added\n\n- **Query result field IDs** — `get_async_query_results` now includes a `requested_field_ids` list in completed responses: the field IDs you requested, in the same order as the data columns (`requested_field_ids[i]` labels the i-th value in each row). This makes it easier to map result columns back to the fields that were requested.\n- **Field remapping visibility** — when a requested field ID resolves to a different canonical ID (e.g. an alias, different casing, or underscores), `get_async_query_results` also returns a parallel `canonical_field_ids` list (same order) so clients can reconcile any stored field IDs (for example in a saved dashboard) against the canonical values. A note additionally highlights substantive remaps (aliases/synonyms); cosmetic differences that only involve casing or underscores are left out of the note since they resolve automatically. When nothing was remapped, `canonical_field_ids` is omitted.\n\n## [1.5.7] - 2026-06-14\n\n### Changed\n\n- **AI image generation branding** — image generation in the media picker is now clearly branded as SuperAI, by Supermetrics. The generate tab, prompt placeholder, generated-image badges, tooltips, and the ready toast all carry SuperAI/Supermetrics attribution, and a note reminds users to review generated images before publishing.\n- **Campaign tool descriptions** — trimmed verbose prose from campaign tool descriptions and parameter docstrings to reduce token usage while preserving all enum values, format hints, and critical constraints. Added `ad_groups`/`ad_group`/`adgroups` aliases to `resource_type` normalization so LLMs that hallucinate these values are silently redirected to `campaigns` instead of erroring.\n\n## [1.5.6] - 2026-06-11\n\n### Changed\n\n- **Contact Supermetrics** — the `contact_supermetrics` tool now directs users to buy standard plans online at https://supermetrics.com/pricing and reserves sales enquiries for special needs (many data sources, accounts, users, or other custom requirements). Reduces unnecessary sales tickets for purchases that can be self-served.\n\n## [1.5.5] - 2026-06-10\n\n### Changed\n\n- **Campaign and resource listing** — the `campaign_and_resource_get` tool now documents that list results (campaigns, assets, pages, posts) default to 50 and explains how to use `max_rows` to retrieve more. Previously the 50-result default was undocumented, so large accounts could appear capped at 50 entities.\n\n## [1.5.0] - 2026-06-08\n\n### Added\n\n- **Google Drive integration** — import images and videos from Google Drive directly into the media picker. Select individual files, multiple files, or entire folders. Supports multiple Google accounts with automatic session caching.\n\n## [1.4.14] - 2026-06-02\n\n### Added\n\n- **Assign users to subscription** — new `add_user_to_subscription` action in the `manage_user_and_team` tool lets you assign team members to a license. Requires `license_id` and `user_ids` parameters.\n\n## [1.4.13] - 2026-06-02\n\n### Added\n\n- **Product feed filtering for Google Ads Shopping and PMax campaigns** — use `product_filter` in `platform_settings` to target specific products from your Merchant Center feed by custom labels, product IDs, brand, condition, or product type. Supports both include and exclude modes.\n\n## [1.4.7] - 2026-05-30\n\n### Fixed\n\n- **Data query date handling** — queries no longer fail with \"Missing value for query start date\" when the AI places date parameters (`start_date`, `end_date`, `date_range_type`) inside the `settings` object or uses alternate key names (`date_from`, `date_to`).\n\n## [1.4.5] - 2026-05-27\n\n### Removed\n\n- **Logout action** — removed the `logout` action from the `manage_user_and_team` tool.\n\n## [1.4.4] - 2026-05-27\n\n### Added\n\n- **AI image generation in asset picker** — the AI Generate tab is now available for all clients, including Claude.\n\n## [1.4.3] - 2026-05-24\n\n### Added\n\n- **Structured output for all tools**\n\n## [1.4.2] - 2026-05-24\n\n### Added\n\n- **Structured output for query tools** — `data_query` and `get_async_query_results` now declare their response shape via MCP `outputSchema`, so clients know the expected fields (schedule_id, status, data rows, error) at discovery time. Responses include typed `structuredContent` alongside the text content for backwards compatibility.\n\n## [1.4.0] - 2026-05-22\n\n### Added\n\n- **Team management tool** — new `manage_user_and_team` tool replaces `user_info` with expanded capabilities. Use `action` parameter to:\n  - `get_info` — get your profile, license, team members, pending invitations, and other teams you belong to\n  - `invite_member` — invite someone to your team by email and role\n  - `login_data_source` — get a login link for a data source\n- The previous `user_info` tool continues to work for existing sessions.\n\n## [1.3.4] - 2026-05-20\n\n### Changed\n\n- **Data source configuration** — large option lists for countries, timezones, currencies, and languages are now replaced with concise descriptions of accepted values, significantly reducing response size. When the same option list appears across multiple report types, it is included once and referenced by pointer.\n\n## [1.2.21] - 2026-05-19\n\n### Added\n\n- **Campaign forecast tool** — estimate ad performance at different spend levels before creating a campaign. Supports Google Ads (keyword forecasts) and Facebook Ads (audience reach estimates).\n\n## [1.2.20] - 2026-05-18\n\n### Added\n\n- ChatGPT Ads integration: you can now create and update ChatGPT Ads campaigns, and fetch data about them.\n\n## [1.2.18] - 2026-05-18\n\n### Added\n\n- Data source discovery now supports a `filter` parameter for narrowing results. If exactly one data source matches, its full configuration is returned automatically.\n\n## [1.2.11] - 2026-05-09\n\n### Added\n\n- Support for Meta's Advantage+ Audience with expand_audience parameter.\n\n## [1.2.10] - 2026-05-08\n\n### Added\n\n- Query results now include a note when dimensions were requested after metrics, since the API always returns dimensions first regardless of request order.\n\n## [1.2.1] - 2026-05-07\n\n### Added\n\n- Asset picker UI for creating ad creatives.\n\n## [1.1.23] - 2026-05-05\n\n### Changed\n- Account discovery no longer returns ds_user or ds_user_display_name.\n\n## [1.1.21] - 2026-05-05\n\n### Added\n- Account discovery now returns `tags` when present, and the `filter` parameter matches against tag values.\n\n### Changed\n- Account discovery only returns group name and currency if they are not empty.\n\n## [1.1.11] - 2026-04-28\n\n### Added\n- **Posts resource type** — list Facebook Page posts that can be promoted as ads via `resource_type='posts'`. Optionally pass `page_id` to pick a specific page, or let it auto-select the first available one.\n\n## [1.1.8] - 2026-04-26\n\n### Added\n\n- New \"Create Campaign\" prompt to guide you through setting up an ad campaign step by step. Optionally specify the ad platform upfront, or let it ask you.\n\n### Fixed\n\n- Pre-defined starter prompts were returning garbled JSON instead of plain text due to a serialization bug. They now work as intended.\n\n## [1.0.6] - 2026-04-17\n\n### Added\n\n- Targeting search now supports LinkedIn Ads — search for interests, industries, job titles, employers, schools, fields of study, skills, degrees, seniorities, and job functions. Six targeting types (interest, industry, school, field_of_study, employer, job_title) now work across both Meta Ads and LinkedIn Ads.\n\n## [1.0.1] - 2026-04-16\n\n### Fixed\n\n- Health check for Facebook Ads was returning ad set IDs instead of campaign IDs due to a legacy field naming mismatch (`campaign_id` = ad set in FA). This caused subsequent campaign detail requests to fail with \"nonexisting field (objective)\".\n- Campaign tools now show a login link when a data source account is not connected, instead of returning a raw \"NO_TOKEN_FOR_ACCOUNT\" error. This matches the behavior already present in data query and account discovery tools.\n\n## [1.0.0] - 2026-04-15\n\n### Changed\n\n- Supermetrics MCP server is out of beta. Starting from this release, the project follows semantic versioning: major versions for breaking changes, minor versions for new features, and patch versions for bug fixes.\n\n## [0.18.5] - 2026-04-14\n\n### Added\n\n- Campaign management now supports LinkedIn Ads (LIA) — create, update, and manage LinkedIn campaigns alongside Google Ads, Meta Ads, Microsoft Ads, and TikTok Ads.\n\n## [0.18.3] - 2026-04-14\n\n### Changed\n\n- Bearer tokens must now use a recognised prefix (`api_` or `otok_`). Tokens with other formats are rejected with 401 instead of being passed to the downstream API.\n\n## [0.18.2] - 2026-04-14\n\n### Fixed\n\n- In some cases, we were caching data query errors, which caused them to be returned repeatedly, even if the underlying issue was fixed. We no longer cache errors.\n\n## [0.18.1] - 2026-04-14\n\n### Added\n\n- `campaign_create` and `campaign_update` tools now accept an optional `url_tags` parameter for campaign-level URL tracking parameters.\n\n### Changed\n\n- Campaign management tools beta is now opened to everyone: `campaign_create`, `campaign_update`, and `campaign_and_resource_get`.\n- Queries without date parameters no longer default to `last_30_days`; the API handles defaults server-side\n\n### Fixed\n\n- Date range types not in the hardcoded whitelist (e.g. `last_31_days`) are now passed through to the API correctly instead of being silently replaced with `last_30_days`\n\n## [0.17.5] - 2026-04-13\n\n### Fixed\n\n- Field discovery filter now matches against report type names (e.g., filtering by 'Posts' returns fields belonging to that report type)\n\n### Fixed\n\n- `get_async_query_results` now correctly signals expired OAuth tokens so clients can refresh automatically, instead of returning a generic error.\n\n## [0.17.4] - 2026-04-11\n\n### Added\n\n- Amazon Ads data source\n\n## [0.15.13] - 2026-04-02\n\n### Added\n\n- New campaign management tools in beta: `campaign_create`, `campaign_update`, and `campaign_and_resource_get`. Create, update, and manage advertising campaigns on Google Ads, Meta Ads, Microsoft Ads, and TikTok Ads directly from conversations. Includes ad group/ad set and ad creation, targeting, extensions, image and video creatives (including AI-generated images), and a full change history with undo support. This functionality will be available for everyone soon; to get access to the beta, please contact Supermetrics support or your customer success contact.\n\n## [0.15.8] - 2026-03-31\n\n### Added\n\n- Data Blending and Semrush Analytics are now available as data sources.\n\n### Changed\n\n- The list of available data sources now reflects your team's actual access, including invite-only and early access sources you've been granted. The list also includes any private connectors your team owns, distinguished by the `is_private` property. Previously, some sources your team had access to may not have appeared.\n- Data source list responses are now leaner: the `status` field is only included for non-released sources (e.g. \"Early access\", \"Invite only\"). The values are now in proper case instead of all caps. The same for categories: `Paid media` instead of `PAID_MEDIA`.\n\n## [0.15.7] - 2026-03-31\n\n### Added\n\n- New `sales` contact type in `contact_supermetrics` tool for submitting sales enquiries and demo requests via HubSpot.\n\n## [0.15.6] - 2026-03-30\n\n### Changed\n\n- The `filter` parameter in `field_discovery` and `accounts_discovery` now supports multiple comma-separated values (e.g. `\"click,impression\"`), returning items matching any of them.\n\n## [0.15.1] - 2026-03-23\n\n### Added\n\n- New `contact_supermetrics` tool: send product feedback or create support tickets directly from conversations.\n\n## [0.14.6] - 2026-03-18\n\n### Added\n\n- New optional `max_rows` parameter for data queries. Defaults to 1000 if not specified. Increase to retrieve larger datasets (up to 10,000 recommended).\n\n## [0.14.5] - 2026-03-18\n\n### Added\n\n- New `filter` parameter for field discovery: case-insensitive text search across field ID, name, description, group, and type. Replaces the `field_type` parameter, which still works for backward compatibility.\n\n### Changed\n\n- Field discovery now returns report types as compact integer indices with a `report_type_legend` array, reducing response size for data sources with many report types.\n\n## [0.14.3] - 2026-03-16\n\n### Added\n\n- Public `/datasources` endpoint listing available connectors.\n\n## [0.14.2] - 2026-03-16\n\n### Changed\n\n- All responses now include `trace_id` in metadata for easier request correlation in support scenarios.\n\n### Fixed\n\n- Tool responses now include the correct server version in metadata.\n- Supermetrics OAuth errors are now always raised as 401 to ensure MCP clients trigger token refresh.\n\n## [0.13.8] - 2026-03-11\n\n### Fixed\n\n- Data queries no longer fail when `report_type` is included for data sources that don't support report type selection.\n- Error messages for unknown fields, incompatible field combinations, and invalid report types now include actionable guidance (e.g. \"call field_discovery\") instead of returning raw API errors.\n\n## [0.13.3] - 2026-03-06\n\n### Added\n\n- Data queries now return a login link when authentication is missing, so users can connect directly from the error message.\n\n### Changed\n\n- Auto-connection creation for no-auth data sources is now dynamic — any connector with `authentication_status: NOT_REQUIRED` is supported, not just a hardcoded list.\n\n## [0.13.1] - 2026-03-06\n\n### Added\n\n- Support for 118 new data sources.\n\n\n## [0.13.0] - 2026-03-05\n\n### Changed\n\n- Tool response notes are now returned as a `notes` array instead of a single `note` string.\n\n## [0.12.9] - 2026-03-05\n\n### Fixed\n\n- Direct tool endpoint (`POST /mcp/{tool_name}`) now correctly handles the settings parameter.\n- Data queries now rescue misplaced settings (e.g. `country`, `list_type`) from root-level parameters into the `settings` object automatically.\n\n## [0.12.4] - 2026-03-04\n\n### Added\n\n- Trace ID in error responses — when a tool call fails, the response now includes a trace ID that users can provide to Supermetrics support for faster troubleshooting.\n\n## [0.12.0] - 2026-03-03\n\n### Added\n\n- Config mode for data source discovery — passing a `ds_id` now returns full data source configuration (capabilities, report types, settings).\n- Authentication status checks with login link generation for unconnected data sources.\n- 10 new data sources: Facebook Pages, Apple Search Ads, Adobe Analytics, Callrail, Google Trends, Instagram Public Data, Snapchat, Taboola, YouTube.\n- Report types included in field discovery output for multi-report-type data sources.\n- Contextual account hints in data query error responses.\n- For some data sources, report type property to field discovery to indicate which fields are compatible.\n\n### Changed\n\n- `ds_accounts` and `fields` are now optional in data queries, supporting data sources that don't require them.\n- Updated tool descriptions to guide agents through a config-driven workflow.\n\n## [0.11.3] - 2026-03-02\n\n### Added\n\n- Filter parameter for account discovery to narrow results by keyword.\n\n## [0.11.2] - 2026-03-02\n\n### Changed\n\n- Improved subtitle for data query tool responses.\n\n## [0.11.1] - 2026-02-26\n\n### Added\n\n- Purchase note on license error responses to guide users toward resolving access issues.\n\n### Changed\n\n- Improved tool titles across all tools for clearer agent integration.\n\n## [0.11.0] - 2026-02-25\n\n### Added\n\n- authentication_status property to data source discovery, with values AUTHENTICATED, NOT_AUTHENTICATED and NOT_REQUIRED.\n\n## [0.10.0] - 2026-02-18\n\n### Added\n\n- Prompts.\n- Title, subtitle and source_url properties to all tool responses.\n"}