Two Facebook Pages, And Adspirer Was Quietly Picking One
If your Meta ad account can run ads from more than one Facebook Page and you didn’t name one, Adspirer used whichever Page Meta listed first. Meta has no “default Page” and the order it returns them in is arbitrary, so an ad could go out under the wrong brand — and it looked like a choice Adspirer had made on purpose.It doesn’t choose any more. When the ad account has exactly one promotable Page, that Page is used and nothing changes for you. When it has two or more and you haven’t named one, the campaign stops before anything is created and comes back with every Page it could run from, each with its name and ID, so you pick. Adspirer won’t guess the linked Instagram account in that case either.list_meta_pages is the new tool behind it: every Facebook Page that can run ads on the account, with any Instagram account attached to it. Ask “which Facebook Pages can I run ads from?” and you get the list without starting a campaign to find out.See your promotable Pages before you launch.
add_meta_ad_set and add_meta_ad. Pausing, resuming, updating, and duplicating are untouched — those work on an ad that already has its Page.→ Choosing a Facebook PageCodex Desktop: Three Messages, No Terminal
The ChatGPT desktop app now has Codex built in, and Adspirer’s Codex plugin installs from a chat window. Switch to Codex in the top-left dropdown, then sendcodex plugin marketplace add amekala/ads-mcp, install plugin, and help me oauth it. Codex runs each one, opens the Adspirer sign-in, and confirms when the connection is live.It’s the same adspirer-ads-agent plugin as the terminal install — 400+ tools, five skills, brand workspace — so nothing changes if you later move to the CLI for scheduled runs. In the sidebar, the terminal guide is now Codex Terminal and the new one is Codex Desktop.Two optional extras follow the setup. Turn on the desktop app’s Computer use and Computer history and Codex can work in Chrome and Excel and remember what you were doing. And if you have an Expert Kit, hand Codex the downloaded folder — it installs the skill and the account’s agent itself, no file copying.→ Codex Desktop setupFour Helper Tools Pulled For Calling A Connected Account Disconnected
diagnose_my_setup, preflight_campaign, whats_changed_since_last_visit, and weekly_opportunities are no longer part of the tool surface. Your assistant doesn’t see them any more, so they won’t come up on their own — treat them as gone.They were misreading which ad platform you meant. Say “meta” and the check looked for the account’s canonical meta_ads name, failed to match it, and answered that no account was connected — on an account that was connected and working fine. That is worse than no answer: it sends you off to reconnect something that was never broken.The other nine Diagnostic & Helper tools are unaffected and still quota-free on every plan, Free included: start_here, suggest_next_action, list_what_i_can_do, get_campaign_spec, validate_campaign_draft, explain_platform_error, why_did_this_fail, verify_campaign_is_live, and usage_value_summary.If you were reaching for diagnose_my_setup to work out where a problem is, ask “why did my recent calls fail?” instead. why_did_this_fail names the platform’s real error on each recent failure, which is usually enough to tell an expired AI-client connection apart from an ad-platform sign-in — the two connections customers most often confuse.→ Diagnostic & Helper toolsChatGPT: Connect Directly For Amazon Ads, ChatGPT Ads, Analytics, and Search Console
The Adspirer app in the ChatGPT App Store is behind. Every update to a ChatGPT app has to be approved by OpenAI, and our latest one hasn’t been published — so App Store users have no Amazon Ads, ChatGPT Ads, Google Analytics, or Google Search Console tools, and won’t see anything new until the next review lands.You don’t have to wait. ChatGPT’s Developer mode lets you add Adspirer as a custom connector that talks tomcp.adspirer.com directly: same account, same sign-in, every tool the day it ships. It takes about two minutes. The ChatGPT setup guide now documents both paths side by side, with a plain comparison so you can pick the one you need.The App Store app still works for Google Ads, Meta Ads, LinkedIn Ads, and TikTok Ads, and you can keep both installed.→ ChatGPT setup — App Store vs. custom connectorVideo Size Stopped Mattering
An 80 MB video ad sometimes came back as “Backend returned a non-JSON response (HTTP 503)”. A 1.3 GB one came back as “timed out after 250s”, three times in a row. Same cause both times: Adspirer downloaded your entire video before handing it to Meta, so the bigger the file, the more likely the upload fell over.It doesn’t download it any more. Adspirer hands Meta the URL and Meta fetches the file itself, so nothing about the upload depends on how big the video is.create_meta_video_campaign, add_meta_ad, and add_meta_ad_set all take the same path.One thing this asks of you: the video URL has to be reachable from the public internet, because Meta is the one fetching it now. A Google Drive or Dropbox link shared with “anyone with the link” works; a private or sign-in-required link does not. If Meta genuinely can’t fetch it, Adspirer falls back to fetching and pushing the file itself.→ Creative assets”No Payment Method Is Set” — On An Account That Has A Card
Before creating a campaign, Adspirer checks the Meta ad account for the things Meta will reject it for. The payment check read the wrong signal: Meta leaves that field empty on an account that has a valid card attached but has never spent — which is exactly the state of every brand-new account at the moment its owner launches their first campaign.So a first campaign got blocked with “No payment method is set on this Meta ad account” on accounts that were funded and ready. Worse, the phantom blocker was listed ahead of any real one, so when something genuine was also missing — usually a promotable Facebook Page — you went and fixed the wrong thing.It now reads Meta’s ownHAS_VALID_PAYMENT_METHODS capability, and it fails open: if Meta’s answer comes back partial or empty, Adspirer doesn’t block a campaign Meta would have accepted. This covers image, video, carousel, and catalog campaign creation.→ Campaign creation failedThe Duplicate Phone Number Problem, Both Halves
A customer added a call asset, couldn’t tell whether it had worked, and added it again. Google stores a call asset’s phone number verbatim and never deduplicates, so the campaign ended up serving two identical phone extensions — and there was no way to list what was on the campaign, no way to pause one, and no way to take one off.Both halves are fixed.Adding is idempotent now.add_call_asset, add_business_name_asset, and add_search_campaign_image check the campaign before they write, and skip when the same asset is already there — telling you it was already present rather than reporting a second success. Pass force=true when a genuine duplicate is what you want.Call assets get a full lifecycle. Three new tools:list_call_assets— every phone number on a campaign, with its country code, status, and the asset ID the other two need.set_call_asset_status— pause a number so it stops showing, or re-enable it, without unlinking anything. Name specific asset IDs, or omit them to change all of them.remove_call_assets— unlink numbers from the campaign. The asset stays in your Asset Library and can be re-linked elsewhere.
list_campaign_extensions grew to match. It used to report sitelinks, callouts, and structured snippets; it now covers call assets, business names, and images too, each with its status — so “what’s actually on this campaign?” is one call rather than four.Find and clear a duplicate phone number on a Google Ads campaign.
Competitor Research No Longer Needs A Google Ads Account
competitor_ads_research reads public ad libraries. It never needed a connected Google Ads account to do that — but it insisted on one anyway, and stopped with “No google_ads account connected” for anyone who hadn’t connected Google. If you advertise on Meta only, the tool was unreachable, even when you explicitly asked for sources=["meta"].It now resolves who you are instead of demanding an account you don’t have. The research runs on whatever sources you name.The Your ads half of the comparison — your own creatives and brand terms placed beside theirs — still needs a connected account on the platform being compared. With nothing connected there you get the competitor findings and no comparison tab, instead of an error and nothing at all.Naming an account explicitly still behaves exactly as before: a wrong or ambiguous account_id errors and tells you which accounts to pick between. Only the requirement to have one at all is gone.Run competitor research on Meta with no Google Ads account connected.
Meta Budgets On Whole-Unit Currencies Were 100× Too High
If your Meta ad account bills in Japanese yen, Korean won, Indonesian rupiah, or one of eight other currencies that have no decimal subdivision, a budget you set through Adspirer reached Meta a hundred times larger than you asked for. A ¥20,000 daily budget was sent as ¥2,000,000.Meta wants budgets in each currency’s smallest unit, and how many of those make one unit depends on the currency: 100 for dollars, euros and most others, but 1 for the eleven currencies that have no minor unit at all. Adspirer multiplied by 100 in every case.The read side hid it. Adspirer divided by 100 to display a budget, so the number it showed you back was the one you’d asked for — correct on our screen, wrong at Meta. That is why this ran undetected.Both sides are fixed. The multiplier is now the one Meta actually specifies for your account’s currency, applied once, at the last step before the request leaves — and budgets, bids, and remaining spend read back with the real conversion and the real currency symbol. A ¥20,000 budget now displays as¥20,000, not $200.Two smaller things came with it. Budget validation no longer rejects legitimate budgets on these accounts — the old fixed ceiling was effectively 100× lower for them, which turned real Japanese and Korean advertisers away. And whole-unit currencies stop rendering a meaningless .00: a Hungarian account reads Ft 5,000, not Ft 5,000.00.→ Meta budget guidelinesChatGPT Ads Campaigns Can Bid For Conversions
A ChatGPT Ads campaign used to optimize for clicks or impressions and nothing else. If you had conversion tracking set up, the campaign couldn’t use it.create_chatgpt_campaign and update_chatgpt_campaign now take a bidding_type — conversions (oCPC), clicks (CPC), or impressions (CPM). On conversions, OpenAI optimizes toward the clicks most likely to convert and still bills you per valid click.Conversions bidding needs exactly one conversion event to aim at, named with conversion_event_setting_ids. Get one from list_chatgpt_event_settings, or create it with create_chatgpt_event_setting. Ask for conversions bidding without an event setting — or with more than one — and the agent tells you so before the request leaves, instead of relaying an opaque rejection from OpenAI.Switch a running ChatGPT Ads campaign to conversions bidding.
Budgets In Your Own Currency, And Budget Edits That Stick
Two money problems, both fixed.Budget changes silently did nothing. Asking to raise a ChatGPT campaign’s daily budget reported success and changed no budget — the number went to OpenAI in the wrong shape and was discarded. It applies now, on daily and lifetime budgets alike, and a lifetime campaign is no longer quietly converted to a daily one. If you tried to change a ChatGPT Ads budget from chat and the campaign kept spending at the old rate, that is why. Check the campaign and set it again.ChatGPT Ads is not a dollars-only platform. Roughly a third of connected accounts bill in AUD, BRL, CAD, GBP, MXN, or NZD, and every budget and bid was labelled in dollars regardless. Budgets and bids are the account’s own currency now — say25 for 25 a day in whatever currency the account bills in — and create and update responses read back the budget and bidding that actually applied, rendered in that currency, so you confirm the number rather than trust it.One consequence worth knowing: OpenAI’s real minimum for a daily budget is 25 a day in the account’s currency, not 1. Adspirer had been enforcing 1, so a smaller budget passed validation and then failed at OpenAI with nothing useful attached. It’s caught up front now, with the account’s currency in the message.→ Budgets, bidding, and targetingExclude A Location — And Keep The Targeting You Already Had
create_chatgpt_campaign and update_chatgpt_campaign gain exclude_location_query and exclude_location_ids, so you can run nationally and skip a state, or target a metro and cut a suburb out of it.The more important half is what happens on an edit. OpenAI replaces a campaign’s targeting wholesale rather than merging it, so changing one side used to erase the other — add an exclusion and the campaign quietly lost its include list and started serving everywhere. Adspirer now reads the current targeting and preserves whichever side you didn’t mention.Two related guards came with it:- A location it can’t resolve is an error, not a wipe. A misspelled place name leaves your targeting exactly as it was and says so, rather than clearing it.
- Serving everywhere is now something you ask for explicitly, with
clear_targeting. Empty location lists no longer mean it by accident.
update_chatgpt_campaign also checks OpenAI’s response against what you asked for and names any field OpenAI kept at its old value — so a change that didn’t take never comes back reported as done.Add a location exclusion without disturbing the existing targeting.
Archiving A ChatGPT Campaign Asks First
OpenAI has no un-archive endpoint. Archive a ChatGPT campaign, ad group, or ad and it is gone for good — but the confirmation gate that guards permanent actions only recognised tools nameddelete or remove, so the three archive_chatgpt_* tools went straight through.They now require an explicit confirmation, and the agent points you at pausing instead when pausing is what you meant. Archive tools on Google, Meta, TikTok, and LinkedIn are unaffected — archiving there is reversible, and nothing about how they behave has changed.→ Safety guardrailsMore Than One ChatGPT Ads Account
ChatGPT Ads authenticates with a pasted Advertiser API key rather than an OAuth login, and one key reaches exactly one advertiser account. That made it the only Adspirer platform locked to a single account — awkward for an agency, and worse for anyone running two brands.Connect a key per account and they all sit side by side. “Connect another account” in the Connections tab adds one; each disconnects on its own, so removing a client doesn’t disturb the rest. How many you keep active at once follows your plan.Nothing changes if you have a single account connected — tools still use it automatically and you never pass an ID. With two or more, name the account you mean.list_chatgpt_accounts shows each one with its account_id, name, and currency, and a request that doesn’t say which account comes back with your list rather than a guess at one.See every connected ChatGPT Ads account, then scope a question to one.
Conversion Tracking You Can Set Up By Asking
Measuring a ChatGPT ad used to mean leaving the conversation: open OpenAI Ads Manager, create a pixel, copy the ID back, create a Conversions API key, define your events. Five tools now do it from chat.create_chatgpt_pixelcreates the web pixel and hands back the site snippet ready to paste into your<head>, along with the Pixel ID and the Source ID you need next. Automatic Advanced Matching — which hashes what your site forms collect so more conversions match — is on unless you ask for it off.create_chatgpt_conversions_api_keycreates a server-side key. The secret is shown once and never again, and by default it’s stored encrypted so Adspirer starts sending server-side conversions straight away.create_chatgpt_event_settingties an event —order_created,lead_created, one of the other supported types, or a custom one — to a pixel or Conversions API source, with an attribution window.list_chatgpt_pixelsandlist_chatgpt_event_settingsshow what already exists.
Set up ChatGPT Ads conversion tracking end to end from chat.
One Field Google Won’t Change No Longer Sinks The Whole Update
A customer asked to make a conversion action secondary and, in the same breath, to leave it out of the Conversions column — where it already was. Nothing happened. Google returned an immutable-field error, and because the update is a single atomic write, the field that was changeable went down with it. Only a retry that dropped the second request worked.The cause: “counts in the Conversions column” cannot be set through the Google Ads API on an existing conversion action. Not for GA4-imported actions, not for native ones. Google derives it from the action’s category and goal setup — and for imported conversions, from Google Analytics. Adspirer had been sending it anyway.It now never goes to Google. Ask for it and:- If the action is already set that way, it’s skipped in silence and the rest of your update applies — which is exactly the customer’s case, now working.
- If it’s a real change, the rest of your update still applies and you’re told to make that one change in the Google Ads UI (Goals → Conversions → the action → Edit settings) or in GA4.
- If it was the only thing you asked for, you get that explanation rather than Google’s opaque refusal.
Search Language Targeting Ends In September, And Says So
Google is removing campaign-level language targeting for Search campaigns in late September 2026. Search ads will match on the language of the ad itself. Performance Max is exempt, and reading a campaign’s existing language criteria keeps working.update_campaign would have started failing on Search the day Google flipped it, with a context error that names nothing you could act on. It now recognises that specific rejection and explains it: Google no longer accepts language targeting on Search campaigns. A language-only update tells you it didn’t apply instead of reporting success, and a mixed update applies everything else and says which part Google refused.Nothing changes before the cutover — Adspirer keys off Google’s own rejection rather than a date on a calendar, so today the setting still writes exactly as it did yesterday. You don’t need to do anything now; when the change lands you’ll get a sentence instead of a stack trace.→ Campaign management on Google AdsIntegration Tools Stop Hiding Until You Connect Them
Google Analytics, Search Console, Tag Manager, and Klaviyo were hidden from your AI client’s tool list until you had connected them. The reasoning was to save you a dead-end call. The effect was a trap: you couldn’t discover an integration existed, so you never learned there was something to connect.It cost a real customer more than a wasted call. They connected Search Console and Tag Manager, their Claude client was still holding a tool list from before those tools existed, and because the server had also been hiding them pre-connection, the agent never tried them once. From the outside it looked like the integrations were broken.Integration tools are now always listed, exactly like every ad platform. Ask for one you haven’t connected and it answers with a prompt to authorize it in Connections — which is the nudge that gets it connected, and a good deal more use than a tool that isn’t there.→ Integration tool referenceA Reused Logo No Longer Breaks Demand Gen And YouTube Campaigns
discover_existing_assets hands back the logos already in your Google Ads account and tells the agent to reuse them as-is. create_demandgen_campaign and create_youtube_campaign then wrapped that value a second time, sending Google a malformed asset reference and getting back an INVALID_ARGUMENT that named nothing useful. Five accounts hit it across both tools over the last 90 days.Both tools now recognize an asset reference that’s already complete and pass it through untouched. Reusing a logo the agent just discovered works, and so does supplying a bare asset ID — the path that happened to work before is unchanged.If a Demand Gen or YouTube campaign refused to create for you with an invalid-argument error after picking up an existing logo, try it again.→ YouTube campaignsCompetitor Research Now Covers Meta, TikTok, And LinkedIn
competitor_ads_research read Google’s ad library — Search, Display, and YouTube. For a competitor whose real budget sits on Instagram or TikTok, that was a report about the smallest part of what they run.Three more ad libraries are now behind the same tool. Ask for a competitor’s Facebook and Instagram ads, their TikTok ads, their LinkedIn ads, or any combination, and they come back in the same gallery — creatives, headlines, offers, formats, and how long each has been running, every one read with vision analysis.Google is still the default. You add the rest by naming them, and each one is another set of lookups, so ask for the platforms your competitor actually advertises on rather than all four out of habit.Two details worth knowing:- Meta carousel ads arrive whole. A multi-card ad used to show its first image and drop the rest. It now renders as a swipeable strip with all its cards, labelled for what it is.
regiondoesn’t apply everywhere. Google and Meta ad libraries filter by market. TikTok’s and LinkedIn’s are worldwide and can’t be narrowed — so those results are labelled worldwide rather than passed off as your market.
Compare a competitor's social ads against their search ads.
The Right Advertiser, Or Nothing At All
A live account asked aboutget-ryze.ai and got back ads from a haircare brand and a GP-booking service. Two strangers, presented as their competitors. The domain had been matched loosely by name, and nothing checked whether the advertiser it landed on was actually the company you asked about.Matching is now strict everywhere. A domain resolves to one advertiser and is confirmed against the links inside that advertiser’s own ads where the platform exposes them — a check that rejects lookalike domains rather than accepting anything that merely contains your competitor’s name. When a match can’t be confirmed, you get an honest empty result instead of somebody else’s creatives.Where a platform gives no website to verify against — TikTok and LinkedIn identify advertisers by name only — the result says so, so you can judge the match yourself.Two smaller honesty fixes shipped with it. An empty TikTok or LinkedIn result now reads “no ads found on TikTok (worldwide)” rather than “none in this market”, which was a claim about where a competitor advertises that Adspirer had no basis for. And one bad domain in a list no longer kills the whole report — the rest run, and the ones that couldn’t be read are named.→ Tool catalogCompetitor Video Opens Where It Actually Plays
Yesterday’s release played competitor video inside the card. In Claude that turned out to render a blank white frame that never played — the sandbox around the card blocks an embedded player, and no setting on our side changes that.So the video no longer pretends to play in place. You get the poster frame with a Watch on YouTube / Meta / TikTok / LinkedIn ↗ link, and clicking it opens the ad on the platform it runs on, in a new tab. The frame is still read with vision analysis exactly as before, so the written analysis of the video is unchanged.The Summary tab also stopped growing without limit — a long analysis scrolls inside the card now instead of stretching it down the page. And the Your ads tab no longer appears when there is nothing to put in it; it used to tell customers who were already connected to “connect an ad account”.→ Tool catalogGoogle Tag Manager Joins Your Connections
“Is my Meta pixel actually installed?” and “why isn’t this conversion firing?” were questions your agent could see the symptoms of and not the cause.Google Tag Manager is now a connectable integration, alongside Google Analytics, Search Console, and Klaviyo. Connect it at adspirer.ai/connections and the agent can read the tags and variables in your containers — which conversion pixels, analytics, and remarketing tags are on your site, and how each is configured.It can also create or update a tag or a variable. That writes to a live container firing tracking on your real website, where a wrong edit breaks conversion tracking everywhere at once, so the agent confirms the exact change with you first and leans on the read actions for diagnosis.Check whether your conversion tracking is really installed.
One Integration, More Than One Account
An integration held exactly one account. One GA4 login, one Search Console user, one Klaviyo. Agencies with a client’s analytics and their own, or anyone whose properties sit under two logins, had to disconnect and reconnect to switch.Every integration now holds several accounts at once, the same way ad accounts already work — all equal, no primary. Add one with Connect another account on that integration’s card in Connections, and each account gets its own row you can disconnect on its own. How many you can connect follows your plan’s account limit.When an integration has more than one account, tell the agent which one you mean and it uses that; ask and it lists what it can see. With a single account nothing changes — you say nothing and it resolves as it always did.→ Integration tool referenceCompetitor Video Ads Are Read, Not Skipped
A large share of what advertisers run is video, andcompetitor_ads_research was stepping straight past all of it. A competitor’s video ad came back as nothing at all.Now each video ad’s poster frame is pulled from the ad-transparency listing and read with the same vision analysis an image ad gets. The video shows up in the gallery with its headline, offer, format, and run duration alongside everything else. Click the frame and the ad plays inline in the card; close it and you’re back in the gallery exactly where you left off.One frame is described as one frame. Adspirer reads what that frame shows and doesn’t narrate the rest of a video it hasn’t watched.The Competitor Card Splits Into Three Tabs
The card stacked the written analysis, the competitor gallery, and your own ads into one continuous scroll — and the analysis arrived with its formatting showing as raw characters, literal## and ** sitting in the middle of sentences.Both are fixed. The analysis renders as formatted text with real headings and emphasis, and the card is now three tabs — Summary, Ads, and Your ads — so you can read the takeaway first and then go look at the creatives behind it.→ Tool catalogcompetitor_ads_research — Their Live Ads, Next To Yours
Ask what a competitor is advertising and you now get their actual ads back: creatives, headlines, offers, calls to action, formats, and how long each one has been running. They come from public ad-transparency sources, and every creative is read with a vision model so the copy and the offer are extracted rather than left as an image you squint at.The second half is the part an ad-spy tool can’t reach. Your own connected accounts land in the same answer — the ads you’re running, and any competitor brand terms you’re already paying for.You supply the domains. competitor_domains takes websites, not brand names — semrush.com, not “Semrush”. A bare brand name returns nothing, so if you name a company without a website the agent asks for one instead of guessing. It never invents a competitor list for you either. region takes an ISO country code and defaults to your own account’s market.Running more than one ad account? Pass account_id (or customer_id — same field) to scope the your-ads half of the comparison to one of them. Leave it off and the comparison covers every connected account and tells you so.In ChatGPT and Claude the result renders as an interactive card with a scrollable creative gallery; every other client gets the same findings as text. Available on Pro and Max.Put two competitors' live ads next to your own account.
Google Search Console Joins Your Connections
Your agent could see what you pay for in Google Ads and what happens on the site afterwards in GA4. The half in between — what you rank for without paying — wasn’t there.Google Search Console is now a connectable integration, alongside Google Analytics and Klaviyo. Connect it at adspirer.ai/connections and the agent can read organic-search performance for any site you’ve verified: clicks, impressions, CTR, and average position, broken down by query, page, country, device, or date.The useful part is the comparison. Paid and organic search results for the same query now sit in one conversation, so “which of my top Google Ads keywords do I already rank for organically” is a question your agent can actually answer.It can also ask Google to re-crawl a page after you publish or update one. That one’s a write, so the agent confirms the exact URL with you first.Find paid keywords you're already winning organically.
Bid For The Top Of The Page: Target Impression Share
Impression-share bidding meant a trip to the Google Ads interface.update_bid_strategy now accepts TARGET_IMPRESSION_SHARE alongside Target CPA, Target ROAS, Maximize Clicks, and Maximize Conversions.You set two things: where you want to appear — absolute top of page, top of page, or anywhere on the page — and the share of auctions you want to win there, 1 to 100.Send a max CPC ceiling too. Without one, a target of 90% at the absolute top will chase that number as far as your budget allows. The ceiling is a plain amount in the ad account’s own currency, so a €4 ceiling is 4 — not 400, and not converted to dollars.Switch a brand campaign to impression-share bidding with a bid ceiling.
A Bidding Switch That Said “Done” And Changed Nothing
This one affected every bid strategy change, not only the new one. Moving a campaign from one strategy to another — Maximize Clicks to Maximize Conversions, say — could come back reporting success while Google quietly kept the old strategy. The response said the change landed. The campaign carried on bidding exactly as before, and nothing in the reply gave you a reason to check.That’s fixed. And because a false success is the hardest kind of failure to notice,update_bid_strategy now reads the strategy back from Google after writing it and returns an honest error when the campaign isn’t on the strategy you asked for. A change Google declines can no longer be reported as a change that worked.Edit A Conversion Action Instead Of Rebuilding It
Changing anything about a live conversion action — its name, its default value, how long its click window runs — meant doing it in the Google Ads interface, because Adspirer could only read conversion actions or create new ones.update_conversion_action edits one in place. Pass the conversion action ID plus whatever you want changed: name, category, status, value and currency, counting type, click-through and view-through lookback windows, whether it counts in the Conversions column, whether it’s primary for its goal, or its attribution model.Only the fields you pass change. Everything else stays as it is, and the tool never removes a conversion action — to stop one counting, set status to PAUSED, which you can undo.Value changes are handled carefully on purpose: a conversion’s value, currency, and always-use-default setting move as a set, and if Adspirer can’t read the action’s current settings first, the update fails rather than guessing. Smart Bidding reads those numbers, so a value silently rewritten to zero is worse than an update that didn’t happen.Widen a conversion action's click window without touching anything else.
bulk_update_keyword_status — Pause 300 Keywords In One Call
Pausing a list of keywords meant one update_keyword call per keyword. The only bulk option was remove_keywords, which permanently deletes — so the fast path and the safe path were different paths.bulk_update_keyword_status sets status on up to 300 keywords in one ad group in a single call, in both directions: PAUSED or ENABLED. It’s fully reversible, and re-running it on a keyword already in the target status does nothing, so a retry is safe.You pass explicit keyword IDs. There is deliberately no “pause everything” mode — that’s how a whole ad group gets switched off by accident. The delete-confirmation gate now points bulk-pause requests here instead of at remove_keywords.Pause a batch of underperforming keywords without deleting them.
Meta Updates Now Show You The Value They Applied
A successful Meta update replied with field names only — “Updated Fields:daily_budget”. Not the value. So a budget that landed wrong was invisible in the response, and neither you nor your assistant had anything to catch it against.Every Meta update tool now echoes each field with the value that was applied, money rendered in the ad account’s own currency — an Australian account reads A$2,000.00, not a dollar sign bolted onto the number. That covers campaign, ad set, ad, and the three catalog update tools. Each response ends by asking you to check the values before moving on, because they are live at that point.Catalog updates used to be the worst case: editing only a product set, pixel, or retargeting audience could report an empty change list on a successful write. Those fields now come back under readable names.→ Meta Ads integrationThe Conversion Audit Was Passing Accounts It Had Never Read
If you manage Google Ads through a manager (MCC) account,audit_conversion_tracking was sending the wrong manager account on every request. Google refused it, the Google checks abstained, and the audit still printed a Grade A — a clean bill of health on an account it had not actually examined. Around 547 manager-managed accounts were affected.Shared agency accounts had a second version of the same problem. Performance rows are stored under whichever teammate’s login collected them, and the audit only counted rows belonging to you — so a colleague auditing a shared account saw zero conversion volume and got a “0/0 stable” pass. LinkedIn audits returned that same false pass for every account, from a platform-name mismatch.Both are fixed, and the report is honest about the difference between checked and healthy and couldn’t check: when a critical check can’t run, the header now reads Incomplete rather than showing a grade. diagnose_funnel no longer reports that “tracking checks out” on the back of an incomplete audit.→ Multi-client agency setupThe Expert Kit Ships An Agent Instead Of Overwriting Yours
The Prompt Engineering Playbook used to tell you to copy itsAGENTS.md to your project root. That is a single well-known filename — so the step replaced whatever was already there with “work only on Google Ads account NNN”, and a coding agent that had been useful for your own work stopped being useful for anything else.That step is gone, and it was never necessary. Every one of these clients has a first-class slot for exactly what an Expert Kit is, so the kit now generates the agent definition itself — .claude/agents/, .cursor/agents/, .agents/agents/ as markdown, Codex as TOML. Your account instructions become that agent’s system prompt, the file points at the skill, and on Claude Code, Codex and Antigravity it declares mcp.adspirer.com too, so there’s no connector left to wire up. A uniquely-named new file can’t clobber anything, and uninstalling is deleting it.Skills now install at project scope, never the ~/ home paths — those loaded one account’s ads agent into every unrelated repo on your machine.Setup is now per client, and every claim was re-checked against that vendor’s own documentation:- Claude — five steps: create the project, upload the skill, paste the agent instructions into the project instructions, add the prompt book to project knowledge, connect. Skills are on every plan, including Free (we had said paid-only), the upload control is Add rather than ”+ Create skill”, and Team and Enterprise do this under Organization settings. Teams can upload once for the whole org instead of once per seat.
- ChatGPT — instructions and files, in a project. ChatGPT chat can’t install a standalone skill; OpenAI scopes those to Codex, including Codex running inside the desktop app.
- OpenClaw — its own steps. It’s a workspace-scoped gateway, not a project-based IDE.
- Windsurf — removed from the kit. Cognition renamed it Devin Desktop, it isn’t on the Agent Skills client list, and nothing documents the desktop app loading a local skill. This does not affect using Windsurf as an MCP client — that setup is unchanged.
TikTok Lead Generation Campaigns Can Be Built At All Now
Lead generation with a TikTok Instant Form was structurally impossible here — not because of one bug, but because thepage_id that attaches a form to an ad was dropped at six independent points between your request and TikTok. Each one was fatal on its own. All six are fixed.list_tiktok_lead_pages lists the Instant Forms on your advertiser with the page_id each one needs, and says whether the form is PUBLISHED — TikTok won’t let a draft be attached to an ad.Start here, though: an Instant Form is the minority path. Most live lead-gen campaigns capture leads on your own site instead, with a pixel on the ad group and optimization_event=FORM. Run list_tiktok_pixels for that route. Use an Instant Form when you specifically want the form hosted inside TikTok.Three ad group settings that TikTok requires for lead gen — and which it reported only as the useless “There was an error with the Lead Generation advertising objective” — are now set for you:- The ad group is promoted as lead generation, not as a website visit
- A custom bid is set, because TikTok refuses its own no-bid strategy on this objective
- Placements are named explicitly, because automatic placement is rejected
add_tiktok_ad had been sending both; it now carries exactly one destination, matching campaign creation.Launch a TikTok lead generation campaign on an Instant Form.
Meta Failures Now Hand You The Identifiers Meta Sent
A customer spent three days isolating a Meta ad set publish failure — twelve controlled tests, then rebuilding the campaign by hand in Ads Manager to compare — and finally asked us for the error code, subcode andfbtrace_id. Adspirer had all three on every one of his failures and printed none of them. Across the previous 30 days, 2% of Meta errors reached a customer carrying an fbtrace_id.Without those, there is nothing to act on and nothing to quote to Meta support. They now trail the error as their own reference line, so a failure that Meta sends without identifiers reads exactly as it did before.Two routes — including add_ad_set, the customer’s failing call — had hand-rolled their own error handling and were the last Meta write paths still discarding the identifiers. All 32 Meta write paths behave identically now. When Meta sends a title and an explanatory sentence but no user-facing message, you get the sentence too, rather than a bare title.→ Meta Ads troubleshootingMeta Budget Fields Said “Cents”. They Were Never Cents.
Every caller-facing description on a Meta money field — budgets, bids, spend caps, spend targets — told your assistant to send cents, or to convert to USD. The tools have always taken the value in the ad account’s own currency, and converted internally.An assistant that followed the description literally sent2000 for a 20/day budget, and Adspirer converted it again. That is a 100x budget, on update_meta_campaign and update_meta_ad_set above all.Every Meta money-field description is now uniform: the ad account’s own currency, as a decimal. For 20/day, send 20. No conversion arithmetic changed — the tools behaved correctly the whole time, and only the instructions were wrong. The project-setup skill, which had been stamping “Meta = CENTS” into generated brand context, is corrected too.→ Meta budget guidelinesTwo TikTok Tools That Had Never Worked Are Gone
create_tiktok_campaign succeeded zero times in 176 attempts across 33 customers over the past year. create_tiktok_carousel_card never worked either. Neither was fixable: TikTok’s in-feed placement requires a video creative, so a single-image in-feed campaign is rejected on principle, and the carousel tool was built against an endpoint that doesn’t accept the value it was sending.Both are removed. Asking for them now returns a clean “unknown tool” with a pointer to what to use instead, rather than a campaign that half-builds and then fails.create_tiktok_video_campaign is the creation tool, and it now honours all three creative sources its schema has advertised since April:video_url— a public MP4/MOV that Adspirer uploads for youvideo_id— a video already in your TikTok library, reused without re-uploadingtiktok_item_id— an organic post boosted as a Spark Ad
add_tiktok_ad with an existing video_id used to fail with “You must upload an image”, because TikTok wants a cover alongside the video; Adspirer derives the cover itself.Find Your Pixel Instead Of Guessing At It
Conversion campaigns were TikTok’s largest failure cluster — 124 attempts, 27 customers, one success. You had no way to discover a pixel or the events it accepts, so both got guessed at.list_tiktok_pixels returns each pixel on the advertiser with the numeric pixel_id TikTok requires — not the alphanumeric Pixel Code, which TikTok rejects — and the exact optimization_event values that pixel supports. Pixels with no events configured are flagged as unusable for conversion optimization rather than handed back as if they’d work.Adspirer no longer defaults optimization_event to COMPLETE_PAYMENT. The valid set is per-pixel, so a fixed guess is simply wrong for anyone whose pixel doesn’t carry that event. Ask for a conversion campaign without one and you’re told to run list_tiktok_pixels for the real list.A Conversion Campaign That Was Quietly Built As Something Else
WEB_CONVERSIONS was missing from all three creation paths, so it fell through to each one’s default. A campaign you asked to optimize for conversions was built as video views or traffic — and it still spent, with your purchase pixel attached to an ad group optimizing for something else entirely. If your TikTok conversion campaigns have been underperforming without an obvious reason, this is worth a look at what actually got built.WEB_CONVERSIONS maps correctly now in all three.list_tiktok_ad_videos — Reuse A Video You Already Uploaded
Lists your advertiser’s video library with the video_id for each, so a second ad from the same video doesn’t mean a second upload. discover_tiktok_assets used to claim TikTok’s API “does not support listing or searching existing assets,” which was never true; it covers your image library and now points at the video tool for videos.Pixel and video lookups also raise a real error when TikTok’s API fails. A timeout or a permission denial used to render as a confident “no pixels on this advertiser,” with instructions to create one you may already have had.What TikTok Genuinely Doesn’t Allow, Said Plainly
- Image-only in-feed ads are rejected by TikTok, not by Adspirer. Images are supporting assets alongside a video creative —
upload_tiktok_imagesanddiscover_tiktok_assetsfeedimage_idsinto a video ad. - Carousel ads can’t be built through the API. Build the carousel in TikTok Ads Manager, then boost that post here as a Spark Ad with its
tiktok_item_id.
Set up a TikTok conversion campaign with the right pixel and event.
Your App Campaign Read Back As A Blank “MULTI_CHANNEL”
Google files App campaigns under the channel typeMULTI_CHANNEL, and that was all list_campaigns and get_campaign_structure told you. No app, no store, no bidding goal — nothing identifying which app the campaign promotes or what Google optimizes toward. If you run a portfolio of apps, that’s the first thing you need before touching a budget or a bid.Campaign reads now name it:- The sub-type — an App campaign says it’s an App campaign instead of hiding behind
MULTI_CHANNEL. - The promoted app and its store — the Play package name or App Store ID Google holds, and which store it points at.
- The App bidding goal — install volume, installs at a target cost, in-app conversions, return on ad spend, or pre-registration volume. What Google is actually optimizing toward.
raw_data. Search, Shopping, PMax and every other campaign type read back exactly as before.A Live Target CPA That Reported As No Target At All
Google stores a target CPA or ROAS in one of two shapes: as a standalone Target CPA / Target ROAS strategy, or as a target sitting on top of Maximize Conversions / Maximize Conversion Value. Adspirer only read the second shape. A campaign running a standalone $2.00 Target CPA came back with no target at all — so asking “what is this campaign bidding to?” got you silence about a campaign that was very much bidding to a number.Both shapes are read now, and the readback says which one you have. A bare Target CPA is a standalone strategy; Target CPA (target on Maximize Conversions) is a ceiling on a maximize strategy. They behave differently, and the difference is worth knowing before you move one.update_bid_strategy Stops Handing You Google’s Opaque Rejection
On an App campaign the bidding strategy is paired with the App bidding goal, and Google refuses a mismatched pair with “bidding strategy is incompatible with the goal type” — which tells you nothing about which half to change. Campaign creation already enforced the pairing. Updates didn’t know App campaigns existed, so the two disagreed.The check now runs before the call reaches Google. If the strategy you asked for doesn’t fit the campaign’s goal, you get the goal, the strategy that goal requires, and both ways forward: change the goal in Google Ads (which resets the campaign’s learning — your decision, not something Adspirer does behind a bid change), or use the strategy that matches the goal you have. Non-App campaigns are untouched, and a goal Adspirer can’t identify goes to Google rather than being blocked on a guess.Installs And Cost Per Install Were Zero On Every Google App Campaign
Adspirer wasn’t collecting Google’s app-install metric at all, soinstalls read 0 on every Google app campaign while Google reported six figures of installs over the same window for a single account. Installs, cost per install, and post-install conversions are collected now.Two things worth knowing. Cost per install is reported only when there are installs — no installs means no CPI, rather than a number with nothing behind it. And periods already collected stay at zero until they’re re-collected, so a June app campaign still looks flat when you look back at it.Read an App campaign back before you touch its bids.
”Campaign Updated Successfully” Now Means The Budget Actually Changed
When you asked Adspirer to change a campaign’s daily budget and Google rejected the change,update_campaign came back with “Campaign updated successfully” anyway. The failure was logged somewhere you couldn’t see it. If you were moving budget through an agent — lifting the cap on a winner, cutting one on a loser — you got a confirmation for a spend cap that had not moved.Budget updates now report what actually happened:- The budget was the only thing you asked to change, and it failed. You get a failure that says plainly that nothing on the campaign changed, with Google’s own reason attached.
- Other changes landed but the budget didn’t. You get a failure that names exactly which changes did apply and don’t need re-running, so your retry is the budget alone rather than the whole call.
- Adspirer couldn’t find the campaign’s budget at all. This used to be indistinguishable from success. It now says so, and names the likely causes — the campaign doesn’t exist, it was removed, or the account doesn’t grant access to its budget.
- A budget change that works names the new amount in the list of applied changes, instead of asserting success in general terms.
Meta App Campaigns Stop Bouncing Off “Mobile Targeting Mismatch”
App-promotion ad sets were the single largest cluster of Meta campaign-creation failures. Meta rejected them with “The app you’re trying to create an ad for is on a different operating system than targeting settings for this ad set” — because the campaign named an app without constraining the targeting to that app’s OS.Adspirer now reads the OS off your app’s store URL and sets it for you. An App Store link targets iOS, a Google Play link targets Android, and either way the ad set is constrained to mobile — an app install can’t be fulfilled on a desktop. This applies wherever an app ad set gets built: image, video, and carousel campaigns,add_meta_ad_set, and update_meta_ad_set when you repoint an existing ad set at an app on the other platform.You can override it with user_os if you need to. If that override contradicts the store URL, Adspirer stops and says so instead of forwarding Meta the exact pair it rejects.list_meta_promotable_apps finds your app instead of you guessing at it. App campaigns need the numeric Facebook App ID — not an iOS bundle ID, not an Android package name — and customers were guessing (a literal YOUR_FACEBOOK_APP_ID reached Meta in production). The new tool lists the apps your ad account can promote, each with its App ID and the store URLs Meta already holds, so both fields get filled without leaving the conversation. Apps with no mobile store listing come back separately with the reason, rather than quietly missing.Launch a Meta app-install campaign without hunting for IDs.
Your Meta Video Completion Rates Were Zero. They Were Never Zero.
Video view-through and completion metrics — 25%, 50%, 75%, and 100% watched — were being recorded as0 for every account. Adspirer was looking for the completion percentage in the wrong part of Meta’s response, so real numbers were read as nothing: one delivering account had 103,316 quarter-views and 13,823 completions all stored as zero. Anything built on them — Meta video analysis, creative comparisons — inherited the zeros.Newly collected data is correct. Periods already collected before this fix stay at zero until they are re-collected, so a video campaign you ran in July will still look flat when you look back at it.Advantage+ State And Bid Strategy, Readable And Editable From Chat
Campaign reads now includeadvantage_state_info and bid_strategy — so you can ask whether Advantage+ is actually on for a campaign and what it’s bidding toward, instead of opening Ads Manager to check. Meta retired the old Advantage+ App Campaign API object in May; this is the readback surface for the model that replaced it.Campaign-level bid strategy is editable. update_meta_campaign used to refuse and tell you to go adjust it in Meta Ads Manager. It now accepts LOWEST_COST_WITHOUT_CAP, LOWEST_COST_WITH_BID_CAP, COST_CAP, and LOWEST_COST_WITH_MIN_ROAS. The capped strategies need a bid cap on the ad sets first (bid_amount via update_meta_ad_set) or Meta rejects the change.Google Errors That Name The Actual Problem
Broad-match-only Search campaigns. If a campaign runs broad match only (AI Max), Google rejects exact and phrase keywords with an error code newer than the client library can name — so the only thing that surfaced was the placeholder “The error code is not in this version.” Neither you nor your AI client could tell what to fix. Adspirer now reads the campaign’s real match-type setting before saying anything, then explains that this campaign takes broad match only. Exact and phrase keywords on normal campaigns are unaffected.Retail PMax asset groups build in the right order. Google validates an asset group at the end of each batch of asset links, so interleaving asset creation with asset linking could start validation before the required assets existed — and the campaign failed on assets you had actually supplied. Every asset is now created before anything is linked.→ Meta Ads integration · Google Ads integrationA 0.00x ROAS On A Traffic Account Is Not A Failing Account
If your Meta campaigns run traffic, awareness, engagement or link-click objectives, Meta reports no revenue against them — ROAS is0 by design. get_meta_campaign_performance handed your AI client that bare 0.00x with nothing attached, and clients read it as an account in trouble.Every summary number now carries whether it applies to your account’s objectives:- The ROAS row reads “Not applicable” instead of
0.00x, with a sentence underneath naming the objectives behind it — “traffic and engagement campaigns, measured by CPC. ROAS is not a meaningful measure here.” - Your account’s actual primary KPI is named — cost per conversion, cost per install, CPC, CPM, cost per video view, whichever your objectives call for — so the agent leads with the number that matters instead of the first one in the table.
- Lead-gen, messaging and app accounts are described correctly. They expect conversions that carry no revenue, so they’re measured on cost per conversion or cost per install — not reported as broken tracking.
- Accounts whose objectives Meta never recorded are told exactly that, rather than assumed to be traffic accounts.
No More “Scale This Segment” On A Segment You Can’t Target
analyze_meta_audiences used to close with “Best performing segment: X with Nx ROAS. Consider increasing budget allocation” every time. Three fixes:- It names the metric the ranking actually used. On an account with no conversion value the segments are ranked by CTR, so the message now says CTR ranks engagement rather than quoting a ROAS figure that means nothing there.
- Meta’s
Unknowndemographic bucket no longer wins. That bucket holds people Meta couldn’t resolve, so its spend and its attributed value describe different populations and the ratio is fiction — one account showed 623x while every resolvable segment sat at 1.3–2.2x. It is out of the ranking and stays in the age and gender breakdowns as a measured fact. You couldn’t target it anyway. - “Scale” has to be earned. A top-ranked segment without the volume to back the claim now gets a plain statement of what was measured, instead of an instruction to move budget onto the segment we know least about.
Audit One Account, Not All Of Them
audit_conversion_tracking takes an optional account_id (customer_id works too, for Google Ads). Without it the audit sweeps every active account on the platform — a lot of live API calls if you run several — and agents used to narrow it by switching your active accounts, changing state you never asked to change.Scope the conversion audit to a single account.
One Zip, One Folder — The Expert Kit Installs Where You Point It
We audited the Prompt Engineering Playbook kit against the Agent Skills spec and against every client’s own documentation. The skill itself was conformant. The packaging and the setup steps were not.One download, one folder, flat inside. The kit is now a single root folder —SKILL.md, AGENTS.md, PROMPTBOOK.md, README.md, and references/ — which is exactly the shape Claude’s uploader documents and exactly what the filesystem clients want copied into a skills directory. One download now serves every client. Only references/ still nests, because that is the spec’s progressive-disclosure mechanism: the dossier loads on demand instead of burning context on every activation.One instructions file. AGENT_INSTRUCTIONS.md is gone — it was a third copy of text already in AGENTS.md and already behind the kit page’s Copy instructions button. Kits you downloaded before this change keep working exactly as they did.A README that says where each piece goes, per client, so the folder explains itself even if you unzip before reading anything.Setup steps that name the actual path. The wizard now gives Claude’s real route — Customize → Skills → + Create skill, with code execution turned on first — and the literal install directory for coding agents: ~/.claude/skills/ for Claude Code, .agents/skills/ for Codex, Cursor, OpenClaw, and Antigravity, instead of “check its docs”. It also tells you to copy AGENTS.md up to your project root, which is the only place agents actually read it. ChatGPT and Windsurf now route down the paste path, which is the one that works on those clients today.The prompt book is now visible to your agent — as a menu, not a script. It can open PROMPTBOOK.md to suggest a sensible next step, or to find the right approach for something you asked for, and then run just that one. It is explicitly told never to work through the book in bulk or in order, because every prompt in it spends real tool calls. You can also download the prompt book on its own as a .md.Also: an account with nothing to show yet — brand new, or simply quiet — now builds its honest no-recent-activity kit instead of failing. → Prompt Engineering PlaybookA Playbook Generated From Your Own Ad Account
The Prompt Engineering Playbook reads one of your ad accounts — its campaigns, spend history, and current state — and generates a set of agent files you download and install in your AI client:SKILL.md— an operating doctrine scoped to that one account, in the open Agent Skills formatreferences/account-profile.md— a written dossier: what state the account is in, what to prioritize, what cadence to work onPROMPTBOOK.md— starting prompts written against your real campaigns and currencyAGENT_INSTRUCTIONS.md/AGENTS.md— paste-ready instructions for Claude and ChatGPT Projects, and the agents.md file that folder-based clients read automatically
A Hard Gate So “Pause” Never Means “Delete”
Adspirer now hard-gates every destructive tool.remove_* and delete_* tools carry a destructiveHint and won’t run unless the call explicitly passes confirm_delete: true, and a “pause” request is never routed to a delete tool. This closes a class of error where an ambiguous instruction like “pause these keywords” could be interpreted as a permanent deletion. Read tools still auto-run; only irreversible actions are gated. → Tool safety modelGoogle App Campaigns + a Much Deeper LinkedIn
Google App (Universal App) campaigns.create_app_campaign launches campaigns that drive app installs, engagement, or pre-registration across Search, Google Play, YouTube, Display, and Discover — with app-ad creative management. Created PAUSED for review. → Google App campaignsLinkedIn, deepened (now 55 tools). New this week:- Campaign groups — create, update, delete, list, search, and batch-create groups with shared budgets and schedules.
- Pre-launch forecasting —
estimate_linkedin_audience_sizeandforecast_linkedin_campaign_supplyproject reachable audience and expected impressions/clicks/spend at a given budget, so you size campaigns with data. - Full lifecycle — archive, reactivate, delete, clone, and batch-update campaigns.
Google Shopping Campaigns Arrive
Run Standard Shopping campaigns straight from your Google Merchant Center feed — no per-product ad building.link_merchant_center/get_merchant_center_linksconnect your product feed.create_shopping_campaign→add_shopping_ad_group→add_shopping_product_adbuilds the campaign.- Product partition trees (
add_product_groupand friends) let you subdivide the feed by brand, category, product type, or item ID and bid on each partition independently.
search_tools (find the right tool from a natural-language description) and get_tool_schema (fetch a tool’s exact parameters) keep the AI accurate. → How discovery worksManager-Parity Deep Management for Google Ads
Google Ads is now Adspirer’s deepest integration at 147 tools, with control down to the ad-group, asset-group, and product-partition level:- Search — ad-group lifecycle and settings, demographics, audiences, proximity / ad-schedule / device-bid targeting.
- Demand Gen — create campaigns and ads, manage audiences and channel controls across YouTube, Shorts, Discover, and Gmail.
- Performance Max — full asset-group lifecycle, per-asset edits, asset-performance ratings (Best / Good / Low), and listing filters for retail PMax.
- Campaign-level depth — tracking, dates, frequency caps, network settings, and labels.
Ad Ops Agents Get Smarter — and Cross-Platform
- Cross-platform agents. One agent can now reason and act across Google, Meta, TikTok, LinkedIn, and Amazon from a single goal — e.g. “cap total monthly spend at 10,000 CAD across Meta, Google, and LinkedIn.”
- Teach your agent. Upload your own brand rules, target CPAs, seasonal calendars, and SOPs; every run grounds its decisions in your documents.
- Evidence-gated impact. Impact verdicts only make a causal claim when your own data supports it — no more misleading “+54% worse” calls off a tiny sample.
- Rejection-reason chips. One tap tells the agent why you rejected a proposal, so the next run is better.
Meta Advantage+ Catalog — Dynamic Product Ads
Adspirer now runs Meta Advantage+ Catalog campaigns (dynamic product ads / DPA) — the way e-commerce advertisers show the exact products from their feed to the right shopper without hand-building an ad per SKU. 16 new Meta tools (Meta Ads is now 54 tools):- Discover & prepare —
list_meta_catalogs,list_meta_products,list_meta_product_sets,create_meta_product_set, andvalidate_catalog_readiness(a pre-flight that tells you whether your catalog + pixel data supports retargeting or prospecting only, before you spend). - Launch & manage —
create_meta_catalog_campaign(prospecting or retargeting, created PAUSED) plus catalog ad-set and ad management. - Optimize —
analyze_meta_catalog_performance,get_meta_product_performance(per-SKU ROAS),detect_meta_catalog_waste, anddiagnose_meta_catalog_funnel.
Build, Approve, and Share Ad Ops Agents
The autonomous Ad Ops agent got a full build-and-run experience:- Gallery + 5-step builder with active-agent cards, background goal-compile so the builder opens instantly, and per-agent detail panels.
- Approvals from the card — review, approve, or reject each proposal in place, with server-side approval counts and a per-agent inbox.
- Impact & Recommendations tabs — see whether approved changes actually added value (fed back into the next run) and a running list of prioritized, ad-focused suggestions.
- Community playbooks — share an agent’s decision logic (goal, rules, and guardrails only — never accounts or budgets) and fork others’ proven playbooks onto your own account.
Shareable Dashboards V2 — White-Label & Adaptive
Shareable dashboards were rebuilt into a data- and platform-adaptive report you can hand to clients:- White-label — upload your own logo, set a custom title and footer, and hide Adspirer branding.
- Adaptive depth — ~20 analysis blocks (Pareto, anomaly z-scores, efficiency frontier, funnel, treemap, waterfall) that appear only when your data supports them, plus per-platform “signatures” for Google, Meta, TikTok, and LinkedIn.
- Prompt-mode — compose a dashboard’s layout from a natural-language prompt.
Community Plugins (v1)
Adspirer can now be extended with open-source, community-contributed analysis tools that appear alongside the built-in ones via thecommunity_plugins router. They’re read-only to your ad accounts, run in a credential-free, sandboxed sub-server, and are loaded from a pinned, reviewed commit of the public Adspirer/adspirer-mcp-community repo. First example: a keyword clusterer that groups your search terms into themes. → Community PluginsAdspirer Now Speaks 116 Languages
The Adspirer dashboard, onboarding, and AI-client setup guides are now localized into 116 languages, with:- Automatic browser-language detection and a one-click language switcher.
- Full right-to-left (RTL) support for Arabic, Hebrew, Persian, Urdu, and more.
- A language preference that’s remembered across devices.
Autonomous Ad Ops Agents Go Live
Adspirer’s autonomous Ad Ops agents are out of beta. Give an agent a plain-English goal and a cadence, and it monitors your accounts on a schedule and proposes every change to an approval queue — find winners to scale, wasted spend to cut, budgets to rebalance, CPA/ROAS drift to correct, or broken conversion tracking to flag. Nothing spends or changes without your approval, enforced server-side. Available on Plus, Pro, and Max. → Autonomous Ad Ops agentsRun Ads Inside ChatGPT — New: ChatGPT Ads (OpenAI Ads)
Adspirer now supports ChatGPT Ads (OpenAI Ads) — pay-per-click “chat card” ads that render inside ChatGPT responses, with 31 tools to launch, manage, and measure them conversationally from ChatGPT, Claude, or any connected AI client. (This also brings Adspirer’s total tool surface to 340+.)- Connect once with an API key. ChatGPT Ads is Adspirer’s first non-OAuth platform: paste your OpenAI Advertiser API key in the Connections tab (one key = one ad account). It’s stored encrypted, and the chat agent never sees it.
- Launch in one shot, or manage granularly.
launch_chatgpt_adbuilds the whole ad from a description (URL, headline, body, image, budget, geo), or use full campaign/ad-group/ad controls (list, get, create, update, pause, resume, archive). - Paused by default. Nothing serves or spends until you resume the campaign, and the agent always speaks in dollars, not micros.
- Honest review status. Adspirer reports OpenAI’s ad-review state (in review → approved/rejected) and flags policies up front — notably that third-party AI services are disallowed.
- Conversions via the OpenAI pixel and Conversions API, with a built-in test event to verify tracking.
Meta Performance: Conversions That Reconcile With Ads Manager
The Meta performance dashboard now shows a full conversion-action breakdown and highlights the purchase-class event that matches the “Results” column in Meta Ads Manager. Meta’stotal_conversions sums every pixel action (add-to-cart, initiate-checkout, purchase, and more), which could make the dashboard headline look far higher than Ads Manager’s purchase count. Now you can see exactly which figure reconciles — no more chasing a phantom discrepancy. CPA, ROAS, and deltas are unchanged.Google Ads: Per-Ad Performance, Creative Export & Complete Asset Discovery
get_ad_performance— a per-ad breakdown (one row per ad) with impressions, clicks, CTR, cost, conversions, conversion value, CPC, CPA, ROAS, video views, ad strength, and a live flag — plus a head-to-head comparison when an ad group has multiple ads. Covers Search, Display, Demand Gen, and YouTube.get_ad_creative— export the creative composition of existing ads: YouTube video IDs and thumbnails, downloadable image URLs with roles and dimensions, every headline/description/CTA, and carousel cards.discover_existing_assetsis now paginated across all asset types, returning your complete asset inventory instead of silently capping — with downloadable image URLs and a clear path forward when a square logo is missing (previously a dead end for Performance Max).
Claude Cowork: Self-Serve Fix for “No OAuth Flow Is in Progress”
If Claude’s desktop/Cowork app shows “No OAuth flow is in progress” when connecting Adspirer, that’s a known client-side bug in the Claude app — not an Adspirer problem. The fix takes about 30 seconds: in Claude, go to Settings → Connectors → Add custom connector, enterhttps://mcp.adspirer.com/mcp, and connect from there. → Claude Cowork setupAmazon Ads Joins Adspirer — 61 Tools for Sponsored Products, Brands & Display
Amazon Ads is now a fully supported ad platform, with 61 tools spanning Sponsored Products, Sponsored Brands, and Sponsored Display.- Connect via Login with Amazon; Adspirer discovers your advertiser profiles across North America, Europe, and the Far East and imports each as an ad account.
- Full Sponsored Products lifecycle (campaigns → ad groups → product ads → keywords / targets / negatives), all 7 Sponsored Brands ad types (Brand Registry required), and Sponsored Display.
- Amazon-native analytics: ACOS / ROAS, per-ASIN performance, wasted-spend detection, budget optimization, and a purchased-products cross-sell view. Reporting runs asynchronously via
get_amazon_report.
Meta: EU DSA support + an extra Google extension tool
- Meta ad sets that target the EU/EEA now accept the required DSA disclosure fields (
dsa_beneficiary/dsa_payor), so EU-targeted campaigns no longer dead-end. The fields are sent only when an ad set actually targets the EU/EEA. - Google Ads adds
remove_structured_snippetsto clear stale snippet values before adding fresh ones.
In-Chat Dashboards: Tabs, Date Ranges, Working Buttons & Mobile
The interactive widgets in ChatGPT and Claude got a major upgrade:- Tabbed performance dashboard — Overview / Campaigns / Insights, with KPI tiles, period-over-period deltas, charts, “needs attention” highlights, and 7 / 14 / 30 / 60 / 90-day plus custom date-range switching that re-runs the query live.
- Redesigned conversion-audit and connections widgets — a graded scorecard with an action plan, and an account switcher with a quota meter.
- Action buttons now work — “pause this campaign” or “draft a message for my developer” post straight back into the chat.
- Mobile rendering — widgets now render in the Claude mobile app, with a clean text fallback on clients that don’t support them.
Approved at the Agency Level for the Google Ads API
Google reviewed and classified Adspirer as an agency, full-service ad platform for the Google Ads API and granted Standard Access — which lifts the daily operations cap. Bulk builds, large account restructures, and account-wide optimization now run at full speed, with no daily ceiling on Google Ads work.See Your Connection Health on Usage & Billing
The Usage & Billing page now shows a Connection Health card: whether your AI assistant is connected via MCP, and — per ad account — whether the OAuth link is healthy or needs reconnecting. A Test now button re-checks live, so you can confirm everything’s wired up before you start a session.TikTok Targeting Search Fixed + Redesigned Setup Guide
- TikTok targeting search works again.
search_tiktok_targetinghad been failing for every caller; it’s fixed. Interest keywords are targeted by numeric ID (from that search), not by plain keyword strings — the tool docs now make this explicit. - Redesigned setup guide. The per-client setup experience now has a screenshot carousel synced to the step list and a walkthrough video for Claude Cowork and ChatGPT, plus a standalone Setup Guide you can revisit any time from the web app.
Meta Local Targeting Lands Correctly + Screenshots in Support Chat
City + radius targeting now reaches Meta
Targeting a city with a radius — “everyone within 20 miles of Austin” — now reaches Meta as a real city-and-radius instead of being mis-sent as an invalid country code and silently dropped. Local campaigns on image, video, and carousel ads were effectively running nationwide (or failing) before this fix.- Multiple cities, each with its own radius, now work in a single ad set.
- Location reach modes — choose who in a location you reach: people who live there, were recently there, or are traveling to / interested in it.
- Safer location edits — updating an ad set’s locations now merges onto its existing targeting instead of replacing everything, so a location-only change no longer wipes the rest of your targeting.
Attach screenshots to the support chat
The in-app support chat widget now accepts PNG/JPEG screenshots — click the paperclip, paste, or drag-and-drop. Support reads the image and runs its diagnostics on it, which is far faster for visual issues. Up to 5 images per message (5 MB each); screenshots are processed in-memory and never stored. Conversations also now resume where you left off for up to 7 days (previously 48 hours).Onboarding & Billing Refresh
A polish pass across sign-up and plan management:- App Store connect tabs on the onboarding connection screen, matching how you actually install Adspirer in ChatGPT and Claude.
- Redesigned pricing step — an animated tool-call hero, clearer active-account messaging, and a full-width tier ladder so the plan differences are easy to scan.
- Congrats screen confetti and copy polish once you finish setup.
- “Manage Subscription” now reliably opens the Stripe billing portal from the account menu.
Switch Your Active Ad Account From Chat
You can now change which ad account Adspirer acts on by just asking inside ChatGPT or Claude — including switching between child accounts under the same Google Ads manager (MCC) — without opening the web app.list_connected_accountsnow surfaces connected-but-not-yet-activated accounts (including live MCC child accounts), so the agent can resolve a business name to the right account and switch to it.- Switching respects your plan’s active-account cap: on single-account tiers the new account replaces the active one; on multi-account tiers (annual plans and Max) it’s added to the active set.
- Account switching is a session operation — it never costs a tool call.
Diagnostic & Helper Tools — and Interactive Widgets in ChatGPT & Claude
A new group of 13 read-only “get unstuck” tools is now live across every AI client, on Free and up. They’re quota-free — calling them never counts against your monthly tool calls.Get started, pre-flight, diagnose, and see your value
diagnose_my_setup is especially useful when you’re not sure whether a problem is your AI-client connection or your ad-platform sign-in — it tells them apart. → Full Diagnostic & Helper referenceAnswers render as interactive cards
In ChatGPT and Claude, these tools now render as branded, interactive cards — setup checklists, usage meters, opportunity lists, an account switcher — instead of a wall of text. The cards adapt to light/dark themes and fall back gracefully to plain text on any client that doesn’t render widgets.OpenClaw plugin v2026.5.30
The OpenClaw plugin now bundles the diagnostic & helper tools too (tool count 139 → 140). Reinstall withopenclaw plugins install openclaw-adspirer to pick them up.Google Ads: Clearer Bidding Errors, Reliable Keyword Metrics, Full Ad Extensions
Bid-strategy changes explain themselves
Changing a campaign’s bid strategy when it’s attached to a shared (portfolio) bid strategy used to fail with Google’s opaque “operation not allowed for the given context.” Adspirer now detects the portfolio strategy up front and tells you exactly what to do — detach it from the campaign, or edit the shared strategy itself. Smart Bidding errors (Target CPA / Target ROAS) now include the conversion-tracking prerequisites you’re missing.Keyword research metrics reach your AI reliably
research_keywords now surfaces per-keyword search volume, competition, average CPC, and top-of-page bid range in the structured data your assistant reads — so it stops claiming “per-keyword data isn’t available” when Google Keyword Planner returned it all.Ad copy edits stop failing on duplicates
Editing a Responsive Search or Display ad no longer fails with “Assets are duplicated across operations” — Adspirer automatically de-duplicates identical headlines/descriptions before submitting, and if that leaves you short of Google’s minimum, it tells you exactly how many more unique lines to add.Full ad-extension control
Sitelinks, callouts, and structured snippets now have complete add / remove / list coverage, including the newremove_structured_snippets tool for clearing out stale snippet values. Sitelinks also accept natural field names (text/headline, url/link) and are now suggested whenever you ask about “extensions” or “making my ads better” — you don’t have to know the word “sitelinks.”Meta Ads: Conversion Reporting You Can Trust, Plus Creative & Agency Fixes
Conversions Meta actually reports now count
If your campaigns showed real conversions in Meta Ads Manager but zero in Adspirer, this fixes it. Adspirer now counts:- Pixel custom-event conversions (e.g. a Calendly booking) — the most common “0 conversions” cause
- Lead-form submissions and Messenger conversations
- Offline conversions, with a per-event-name breakdown (“5 invitee_select_time events”, not “5 custom conversions”)
Creating ads with fewer dead ends
- Carousel ads accept your existing assets (the same
existing_image_hashAdspirer’s discovery returns) and validate each card up front — needs an image, headline, and landing URL — with a clear message instead of an opaque Meta rejection. - Dynamic creative (DCO) ads now accept multiple headlines and body texts directly, and Adspirer auto-enables dynamic creative on the target ad set for video as well as image.
- Conversion ad sets now warn you about a missing pixel before Meta rejects the campaign with “promoted object fields missing.”
Agency-grade cross-account safety
If you manage multiple ad accounts and ask the agent to add an ad to an ad set that belongs to a different account, Adspirer now catches the mismatch, names both accounts, and points to the right tool — instead of a misleading “missing image” loop. Deselected (inactive) accounts can no longer be written to until you re-activate them.Adspirer Is Now in the ChatGPT App Store
Adspirer is now an official ChatGPT app — no more Developer mode, custom connectors, or pasted server URLs. Open Apps in ChatGPT, search “Adspirer,” click Connect, and sign in. Setup takes under a minute, and you invoke it in any chat by mentioning @adspirer.- One-click install — find Adspirer in the ChatGPT App Store and connect with OAuth; ChatGPT manages the connection for you.
- No elevated-risk warning — the old Developer-mode + “I understand and want to continue” flow is gone for ChatGPT users.
- Same account, same tools — all 190+ tools across Google Ads, Meta Ads, LinkedIn Ads, and TikTok work exactly as before. If you previously added Adspirer as a custom connector, remove it and reconnect through the App Store; your account and ad platform connections carry over.
Platform Hardening & Resilience Fixes
- MCP base image hardening — all six MCP sub-servers (hub + Google + Meta + TikTok + LinkedIn + Monitoring) pinned to
python:3.11-slim-trixiewith audit-pass cryptography and authlib dependencies. - Container scanning by digest — vulnerability scans resolve images to their content digest instead of the floating
:latesttag, so the report can’t drift between scan time and image promotion. - Tool routing resilience — tighter input handling on Google Ads tool routing and a longer hub timeout for slow Meta calls.
- Watch Agent stability — finding classifier no longer cascades a stuck SQL transaction into a noisy false-positive.
Multi-Google-OAuth, Meta Account Improvements & Per-Platform Cap Messaging
Connect Multiple Google Logins to One Adspirer Account
A single Adspirer account can now hold multiple Google OAuth grants, each with its own non-overlapping set of Google Ads customer IDs. Agencies and consultants who manage Google Ads across separate Google identities no longer need a second Adspirer account.- Adds a second (or third) Google login from the Connections → Google Ads → Add another Google login flow.
- Each grant tracks its own customer IDs; the agent routes tool calls to the right OAuth based on the customer you reference.
- Available on Max annual today; rolling to the rest of the paid tiers behind a feature flag.
Meta Ads — Account Discovery & Asset Handling Overhaul
A set of improvements to how Adspirer works with Meta Business Manager and ad-account-scoped assets.- Business Manager-wide import — when you connect Meta, Adspirer discovers every ad account inside the Business Manager you grant access to, not just the one you happened to click during OAuth. The Manage Accounts modal lists them all so you can pick which ones to activate.
- Per-account asset scoping — image, video, and creative discovery is now scoped to the specific ad account you’re targeting. Eliminates the “this asset was discovered but Meta says it’s not in this ad account” error class.
- Opt-in auto-copy of creatives — when you reuse a creative from a sibling ad account, Adspirer offers to copy it into the target account before launching the campaign (opt-in per call) so the launch doesn’t stall on asset placement.
- Clearer “no account” error — when a tool call can’t find a Meta account, the response distinguishes a stale token from a missing-row state so you (or your AI client) know whether to reconnect or just re-select.
Per-Platform Active-Account Messaging
The active-account cap is per platform — every plan card across pricing and the Manage Accounts modal now states up front how many active accounts you get per platform (Google + Meta + LinkedIn + TikTok each counted independently). When you’re at the cap, the modal shows an inline upsell that links directly into the Adspirer plan picker.Smaller Improvements
- Sidebar rename — “Account Setup” is now Home. Same page, more accurate label for users past initial setup.
- Brief coverage — scheduled performance briefs are scoped to your selected accounts (not just the primary), with full multi-OAuth coverage so a second Google identity’s accounts no longer show up empty.
- Live-tail merge for Google Ads in the brief data fetchers so spend that hit the API after the nightly sweep still lands in your brief.
Plan Limits, Cap Rework & Connections Panel Refresh
Active-Account Caps — New Per-Tier Limits
The big change: annual plans now activate up to 5 accounts per platform, not 1. Monthly plans (except Max) still cap at 1 per platform. Full table:- “Account” means an ad account on a single platform — Plus annual customers can activate up to 5 Google Ads accounts and 5 Meta accounts and 5 LinkedIn accounts and 5 TikTok accounts.
- Every Stripe webhook now reconciles down-tier moves automatically: if you downgrade from Max monthly to Plus monthly, excess actives demote to inactive (deterministically — primary-set-first, then most-recently-synced).
- Caps live in a new
subscription_plan_limitstable so we can adjust without redeploys, and every change is written to atier_limit_changesaudit log. - Defense in depth: the MCP hub also truncates account lists at the tier cap before returning them, so any reconciliation gap can’t accidentally let a downgraded user keep agent access to more accounts than their plan allows.
Onboarding & Connections — Smoothed Out
- Onboarding Step 5 stays put — fixed an issue where the Congrats screen would bounce users back to Step 1 if their AppUser stub hadn’t finished writing after Stripe checkout. You always land on Step 5 post-payment now.
- Connections panel — unified stacked rows — Available Platforms restyled to compact rows that match the Pipedream integration cards below. The Google Analytics + Klaviyo cards no longer hide below the fold.
- OAuth modal always opens — after a successful OAuth, the account-selection modal opens regardless of how many accounts are under your OAuth identity. No more silent auto-pick when you have multiple accounts and didn’t realize.
- Tier-aware Manage Accounts modal with an inline Edit button and a Connections-panel mirror so the active-account picker shows the same state in both surfaces.
- Admin: Plan Limits page with a dry-run preview that counts affected users before you commit a cap change.
Bug Fixes
- “Add another Google login (coming soon)” placeholder is replaced with a Max-annual upsell that explains how to unlock it today.
get_ad_accountsnow filters out deselected (inactive) accounts so they stop rendering as green Active in the Connected Platforms UI.
Google Analytics & Klaviyo Integrations
Adspirer’s first non-ad-platform integrations are live. Plus, Pro, and Max users can now connect Google Analytics 4 and Klaviyo alongside their ad accounts, and the agent can read and act on those properties through chat.What You Can Do
action="list_tools" first to discover what’s available, then action="execute" with the specific Pipedream tool name to call it. The agent handles this two-step automatically.How It Works
- Connect from the Connections tab at adspirer.ai — each integration has its own OAuth popup powered by Pipedream Connect.
- Gated to Plus and above. Free users see the integration card with a “Upgrade” prompt that links into the Adspirer plan picker.
- Disconnect anytime from the same panel; idle connections (>90 days) get pruned automatically to keep the integration list tidy.
Self-Serve Account Deletion in the Chat Widget
Free-tier users can now ask the in-app chat widget to delete their account end-to-end — no email round-trip required. The widget confirms before executing and runs the full GDPR delete (hard-delete + pseudonymize + retain per Article 17(3)(b)).OpenClaw Plugin v2026.5.12
Bumped to expose the new integration tools plus 9 additional Google Ads tools (PMax search themes, audience signals, ad group management) and 3 monitoring tools.Watch Agent Polish & Support Widget UX
Watch Agent Briefs
- Conversion-tracking caveat — briefs now include a “conversion data is reported through your platforms” caveat so anomalies in conversion volume aren’t read as Adspirer numbers.
- Paused vs active classification — briefs no longer call a paused campaign “underperforming” — paused campaigns are explicitly flagged as paused.
- Account names cleaned — fixed a template placeholder that was occasionally showing up in account labels.
- Dead dashboard link replaced — the in-brief “open dashboard” link is now a copy-paste AI prompt you can run in your AI client to drill into the finding.
- Recommendations de-alarmed — toned down “URGENT” language on routine recommendations so high-severity callouts read as actually high severity.
Monitors & Alerts
create_monitorreturns 409 when you try to create a duplicate alert instead of silently writing two.- Digest email values corrected — the daily digest now reports the same value the alert evaluated against, not a stale snapshot.
Support Chat Widget
- Address by name — the in-app support widget greets you by name from turn 1.
- Panel state persists — the widget stays open across page navigations and refreshes, with a time-aware “welcome back” greeting when you return.
Watch Agent, Monitors & Alerts Web UI, and 8 New MCP Tools
Watch Agent — Proactive Signal
The Watch Agent is a server-side AI agent that scans your connected ad accounts every 15 minutes, identifies issues, and emails you a copy-paste re-entry prompt so you can act immediately inside your AI client. No more waiting for weekly reviews to catch a broken campaign.What the Watch Agent does:- Analyzes ROAS, CPA, CTR, spend, and conversion rate across all connected platforms
- Distinguishes true anomalies from normal variance (noise suppression built in)
- Stages pre-validated fix actions (pause campaign, adjust bid, add negatives) alongside each finding
- Sends a finding email with a ready-to-paste prompt when severity ≥ medium is detected
Monitors & Alerts — Web UI
A new Monitors page at adspirer.ai/monitors lets you create and manage performance alerts without opening your AI client. Every alert you create on the web goes to the same backend as the MCPcreate_monitor tool — the Watch Agent reads from one unified table regardless of which surface created the alert.What you can do on the Monitors page:- Create alerts for CPA, ROAS, CTR, CPC, spend, conversions, impressions, clicks, cost per lead, conversion rate, or budget utilization
- Set thresholds with “goes above” or “drops below” operators
- Optional: trigger only after N consecutive days (1–14) — filter out one-off noise
- Scope to specific platforms (Google Ads, Meta, LinkedIn, TikTok) or all connected
- Edit, pause, resume, test (dry-run), and delete alerts in the dashboard
3 More New Monitoring Tools
PDF Reports for Scheduled Briefs
Scheduled performance briefs now attach a PDF to the email. The PDF contains the same tables and charts as the email body — useful for sharing with stakeholders who don’t have Adspirer access.Monitoring tool count: 8 → 16Annual Plans & Max Quota
Annual Quota Pooling
Annual subscribers now get a single pooled allowance for the full year instead of per-month caps. No monthly resets — use your calls whenever you need them.- Pool renews on your subscription anniversary date. Unused calls do not roll over.
- Annual subscribers are never charged overage — the yearly pool is your total budget for the year.
- Max annual (50,000) is intentionally higher than 12× monthly (36,000) as the upgrade incentive for high-volume months.
Max Plan: 3,000 calls/month
The Max plan monthly limit is now formalized at 3,000 calls/month (previously displayed as “unlimited”). This aligns with the Stripe product metadata and all enforcement layers. Max annual subscribers retain the 50,000/year pool with no monthly cap.See the updated Pricing & Tool Calls page.GDPR Article 17 — Right to Erasure
Account deletion requests (submitted via support@adspirer.com) now correctly pseudonymize all associated audit log rows, satisfying GDPR Article 17 right-to-erasure requirements. A bug in the deletion pipeline previously left historical audit rows intact. A one-time backfill also pseudonymized rows from prior deletion requests that had been processed without full erasure.TikTok: 3 Customer-Blocking Fixes
Three bugs from live tool call logs that were causing TikTok campaign creation failures.Local Currency for Budget Floors
TikTok campaign budget pre-flight checks were using USD as the hardcoded currency regardless of the advertiser’s local currency. This caused incorrect minimum budget enforcement for non-USD accounts. The fix fetches the correct currency and timezone from TikTok’s API at OAuth connect time, and backfills existing accounts. A one-time database backfill corrected 167 of 170 affected accounts (3 had expired tokens).Disclaimer Text Format
Ad disclaimer text must be passed as a structured object ({"text": "..."}) rather than a plain string per TikTok’s API requirements. Campaigns with a disclaimer_text were silently failing at TikTok’s server even though the tool accepted the input. The fix wraps string input into the correct object format automatically. Disclaimer text is also now enforced at a max of 90 characters (TikTok’s hard limit).CTA Autocorrect & Full Whitelist
Thecall_to_action field on TikTok ads previously accepted stale values that TikTok’s API would reject at campaign creation time. The field is now backed by:- 30-value authoritative whitelist extracted from TikTok’s rejection response
- 14-alias autocorrect map for commonly used old values:
add_tiktok_ad, carousel). Invalid values that don’t map to an alias return a clear error with the full allowed list.Google Ads: Campaign Control Expansion
18 new capabilities across campaign management, search campaign creation, and asset tools, resolving the top customer-reported gaps from production.Ad Group Pause / Resume
Two new tools give you ad group-level control without touching the parent campaign:pause_ad_group— Pause an individual ad group while leaving the campaign runningresume_ad_group— Resume a paused ad group
update_campaign — Expanded Controls
update_campaign now accepts 6 new parameters:create_search_campaign — Per-Keyword Match Types
Initial keywords in create_search_campaign now accept a mixed format:- Plain strings default to BROAD (backward compatible)
- Objects like
{"text": "running shoes", "match_type": "PHRASE"}set EXACT or PHRASE on individual keywords
add_keywords call to set correct match types.New Asset Tools
Three new tools for attaching assets to Search campaigns:add_business_name_asset— Attach a business name text asset (max 25 characters) at the campaign leveladd_call_asset— Attach a phone number call asset with country code. Accepts an optionalcall_conversion_actionresource name to enable call conversion tracking.add_search_campaign_image— Attach image assets to Search campaigns (logo, landscape, square, portrait). Accepts HTTP URLs or base64-encoded data URIs.
get_campaign_structure — Expanded Fields
get_campaign_structure now surfaces network_settings (Search Partners, Display Expansion), EU political content eligibility, and geo target type for each campaign. get_campaign_targeting responses now include resource_name on each criterion row so you can pass exact IDs to locations_to_remove.Callout Extension Policy
CTA words in callout extensions (e.g., “Learn More”, “Sign Up”) were previously silently dropped. They now generate a warning in the tool response instead of being removed — giving you visibility into which callouts were affected without blocking campaign creation.Google Ads tool count: 89 → 92TikTok Deep Overhaul, Google Ads Conversion Tools, and Meta Adset Performance
TikTok Ads — Full SDK Overhaul + Layer 2
The TikTok integration received its largest overhaul since launch — every customer-blocking bug from production logs was closed and the platform’s full API depth is now accessible.Phase 0 — bug fixes (all customer-blocking): Ad group spec re-architected to 86 fields; creative spec to 59 fields. Image direct-path skips base64 conversion. Slideshow (unsupported by TikTok) removed from code paths. ffmpeg added to Cloud Run for video frame extraction. 5 prod-harness-discovered bugs (pause schema, ValueError hints, image path, envelope, deletes) fixed.Phase 1 — full SDK depth: All 86 ad-group fields and 59 creative fields from TikTok’s marketing API are now surfaced throughadd_tiktok_ad_group and add_tiktok_ad. Previously only a subset was accessible.Layer-1 — validity matrix: 6 common error classes are now caught before the API call — saving tool call quota and eliminating confusing API rejection messages.Layer-2 — new tool and rich targeting:add_tiktok_ad_group now supports interest filters, behavioral keywords, action categories, carrier/device targeting, and language filters — all available through search_tiktok_targeting.Atomic rollback: If campaign creation fails at any sub-step (ad group or ad level), previously-created resources are automatically rolled back. No more partial campaigns left in your account.Google Ads — Conversion Tracking Tools
Two new tools for conversion analysis — separate from the existingaudit_conversion_tracking health check:get_campaign_targeting is also expanded: it now returns all criterion types (location, language, audience, device, ad schedule, topic, content label) instead of just locations and languages.Google Ads — Ad-Group Extensions
add_sitelinks, add_callout_extensions, and add_structured_snippets now accept an optional ad_group_id parameter. Extensions attached at the ad-group level override campaign-level extensions for that specific ad group — useful for ad groups targeting different products or audiences.Meta Ads — Ad Set Performance
A new middle-layer analytics tool between campaign and ad level:Billing — Plan Management UI
The Billing page now supports plan changes without contacting support:- Downgrades — Switch from Pro → Plus or Plus → Free directly from the billing page
- Interval switching — Toggle between monthly and annual billing mid-cycle
- Max plan visibility — Max plan capabilities and tool call limits are now shown inline on the billing page
Reconnect now resumes metric collection
Fixed an issue where reconnecting an ad account after an authentication error wouldn’t actually resume background metric collection. Previously, if Adspirer auto-paused an account because the platform returned a 401/403 (expired token, revoked permissions), reconnecting through the connections page issued a fresh OAuth token but leftmetrics_collection_enabled set to false — so daily collection kept skipping the account. Customers were effectively reconnecting for nothing.Reconnect flows for Meta Ads, Google Ads, TikTok Ads, and LinkedIn Ads now automatically clear auth-error pauses on the same user and platform once the new token is saved, restoring daily metric collection without manual intervention. Admin pauses, free-tier pauses, and other auto-pause types are untouched.Sequential sub-agents for Max plan
Max plan users can now run sequential sub-agents across multiple active ad accounts in a single conversation. Instead of switching primary accounts one at a time, mark multiple accounts as active and let Adspirer fan out tool calls across each — perfect for agencies running cross-account audits, weekly briefs, or bulk optimizations from a single prompt.What’s new
- Active accounts model — Max users can have multiple ad accounts marked active per platform simultaneously. Lower tiers continue with the primary-account model.
list_connected_accounts— New system tool that returns every active account across platforms with IDs, names, and status. Reads directly from the database (zero API calls, doesn’t count against your quota).- Cross-account workflows — A single prompt like “run last week’s performance brief across all my Google Ads accounts” now triggers per-account sub-agents that aggregate into one consolidated response.
- Active set management — Add or remove accounts from your active set at adspirer.ai/connections.
Who this is for
Agencies, portfolio managers, and anyone managing 3+ ad accounts who currently bounces between primaries. See the updated Multi-Account Management guide.Google Display Ads — end-to-end CRUD
Full Google Display Network support joins Search, PMax, YouTube, and Demand Gen. Ships with 27 new MCP tools verified live against Google Ads API v21. Standard Display (full manual control) and Smart Display (Google-managed) are both supported. Display Ads guide →What’s new
create_display_campaign— Standard Display (channel=DISPLAY) and Smart Display (sub_type=DISPLAY_SMART_CAMPAIGN) with a single flag. Creates campaign + default ad group + Responsive Display Ad, all PAUSED.- 5 targeting surfaces — GET / ADD / REMOVE on each:
add_display_audiences— In-market, affinity, custom audiences, user lists, combined audiencesadd_display_topics— Google content categoriesadd_display_placements— Specific websites, apps, YouTube channels, YouTube videosadd_display_keywords— Contextual (always BROAD match on Display)update_display_demographics— Age, gender, parental status, income exclusionsremove_display_criteria— Unified removal across all 5 surfaces
- Full CRUD:
add_display_ad_group,add_display_ad,update_display_ad_creative(colors, CTA, images, videos, promo, format_setting),update_display_ad_group,update_display_campaign_schedule,update_display_frequency_caps, plus remove variants - Geo + language resolvers —
resolve_google_locationsandlist_google_languagesreject ambiguous inputs (“Baja” surfaces 5 candidates) instead of silently falling back to US. All Google campaign types benefit. - RSA + RDA dispatch —
update_ad_headlines,update_ad_descriptions, andupdate_ad_contentnow dispatch on ad type. Responsive Search Ads (3–15 headlines, 2–4 descriptions) and Responsive Display Ads (1–5 headlines, 1–5 descriptions, pluslong_headline) work side-by-side. select_google_campaign_type— Now includes'display'and'demandgen'alongside'search','pmax', and'youtube'with full decision-tree workflows.
OpenClaw plugin update
OpenClaw bumps to v2026.4.13. Tool count goes from 95 → 119 — adds all 22 Display Ads tools + 2 helpers. OpenClaw agent guide →Regressions
None. RSA users see identical behavior plus clearer validator errors. PMax, Demand Gen, and YouTube still hit the same unchanged paths.REST API Reference now live
Every Adspirer tool is now callable over plain HTTP and documented at adspirer.com/docs/api-reference. Same 178 endpoints as the MCP server — same auth, same quota, same write-guards — but over request/response JSON so consumers that can’t speak SSE (n8n, Zapier, Make, cron jobs, GitHub Actions, your own backend) can use them.What’s included
- 178 auto-generated endpoint pages grouped by platform: Google Ads (51), Meta Ads (36), LinkedIn Ads (45), TikTok Ads (29), monitoring (13), general (3), audit (1)
- Interactive “Try it” playground — authorize once with your
sk_live_...key, call any endpoint from the browser against the real API - REST API overview with use-case patterns for Slack ChatOps, daily account briefings, portfolio rollups, alert / auto-pause, SaaS product embedding, and headless CI
- Architecture sequence diagrams for each pattern showing how ingress → Adspirer → egress wires up
Base URLs
Auth
Pass your API key asAuthorization: Bearer sk_live_... — same keys you already use for headless MCP. Generate one at adspirer.ai/keys. Free tier includes 15 calls / month.Idempotency
Write operations accept anIdempotency-Key header. Strongly recommended for n8n, Zapier, and any retry-prone client — a repeated call with the same key returns the cached result instead of creating duplicates.Pay-as-you-go overage for Plus subscribers
Plus plan subscribers no longer hit a hard stop at 150 tool calls. After your included calls are used, you can keep working at 50/month in overage charges.How it works
- Overage billing is auto-enabled for all Plus subscribers
- Your first 150 calls are included in your $49/month subscription
- After 150 calls, each additional call is billed at $0.50 through Stripe
- Monthly overage is capped at 99/month
- Disable overage anytime from your billing page to revert to the previous behavior (hard stop at 150 calls)
Usage notifications
- At 135 calls (90%): one-time notification that overage billing kicks in after 150
- At 151 calls: one-time notification that you’re now on usage-based billing
- All other overage calls: no interruptions — just keep working
Tier-specific messaging
- Plus: Minimal notifications during overage — you’re paying for usage, so no nagging
- Pro: Usage stats shown without upgrade prompts
- Max: No usage hints — high included limit, don’t worry about it
Raw data mode for all performance tools
All 29 performance and analytics tools across Google Ads, Meta Ads, LinkedIn Ads, and TikTok Ads now accept araw_data parameter. When set to true, tools return a compact JSON code block with only raw metrics (spend, clicks, impressions, conversions, CPA, CPC, CTR, CVR, ROAS) — stripped of severity labels, suggested bids/budgets, industry benchmarks, and optimization recommendations.Default behavior is unchanged. Existing markdown output with recommendations is returned unless you explicitly pass raw_data=true.When to use raw data mode
- You run your own attribution model and want raw numbers only
- You want to minimize token usage in AI client responses
- You’re piping metrics into a spreadsheet, dashboard, or external tool
Supported tools
Example
Free tier access fix
Free-tier users who previously had a failed or paused Stripe subscription attempt were incorrectly blocked from using MCP tools. This is now fixed — free-tier users are gated only by their usage quota, as intended.TikTok Ads: correct optimization event values
Theoptimization_event parameter on create_tiktok_campaign, add_tiktok_ad_group, and add_tiktok_ad previously listed invalid values (SUBMIT_FORM, ADD_TO_CART, VIEW_CONTENT, COMPLETE_REGISTRATION, DOWNLOAD, CONTACT, BUTTON_CLICK) that TikTok’s API would reject.Correct values you should use:COMPLETE_PAYMENT, CONVERSION_LEADS, PAGE_VISIT, PHONE_CONNECT, SEARCH, SUBSCRIBE, INITIATE_ORDER, ON_WEB_SUBSCRIBE.If you were passing the old values and getting TikTok API errors, update to the new values above.TikTok Ads: campaign creation reliability
5 fixes to TikTok campaign creation from production testing.- Spark Ads now work with
create_tiktok_campaign— creating campaigns with atiktok_item_id(Spark Ads) orcard_id(Carousel) no longer fails with “Unknown error”. Spark and Carousel ads are now created directly without requiring an image upload. - All TikTok CTAs accepted — previously, only 6 call-to-action values (like LEARN_MORE and SHOP_NOW) were allowed. Now any CTA supported by TikTok works — including CONTACT_US, BOOK_NOW, GET_QUOTE, and others. TikTok validates CTAs server-side.
- Automatic placement fix — campaigns using automatic placement no longer fail with “Missing required field(s): placements.”
- TikTok page URL detection — passing a TikTok page URL (e.g.,
https://tiktok.com/@user/video/123) as a video URL now returns a clear error explaining you should usetiktok_item_idfor Spark Ads or provide a direct MP4/MOV link. - CTA auto-default — when creating an ad with a
landing_page_urlbut nocall_to_action, Adspirer now defaults to LEARN_MORE instead of failing with “External_URL and Call_to_action must exist together.”
Meta Ads: disclaimer acceptance before connecting
When connecting your Meta Ads account, you now see a disclaimer checkbox after entering your email. You must accept the disclaimer — confirming you understand that Adspirer operates independently from Meta’s account enforcement systems — before the Connect button becomes available. Acceptance is recorded for compliance purposes. See Connecting Meta Ads.The Meta Ads page and Security page also now confirm Adspirer has Meta approved Ads Management Standard Access, so users know the app is verified by Meta to use the Marketing API.Platform Terms & Conditions
New users now accept Platform Terms & Conditions as part of onboarding before connecting ad accounts. The terms cover account authorization requirements, rate limit safeguards, platform enforcement policies, financial responsibility, and liability. This replaces the previous per-platform disclaimer prompts with a single, comprehensive agreement.Faster email support
Email support response time improved from 1 business day to 2–4 hours (San Francisco / PST). Reach us at support@adspirer.com.Meta Ads: expanded tool coverage (21 → 36)
Meta Ads now has 36 tools (up from 21), covering the full campaign lifecycle — from browsing and creation to ad set management, creative rotation, and lead form submissions.New tools
- Ad set & ad management:
add_meta_ad_set,add_meta_ad,update_meta_ad_set,update_meta_ad,list_meta_ad_sets,list_meta_ads - Campaign management:
list_meta_campaigns,get_meta_campaign_details,duplicate_meta_campaign,resume_meta_campaign - Creative & lead gen:
create_meta_dco_ad(Dynamic Creative Optimization),get_meta_ad_creatives,list_meta_lead_forms,get_meta_lead_form_submissions - Account discovery:
list_meta_instagram_accounts,list_meta_pixels - Analytics:
analyze_meta_wasted_spend,get_meta_audience_insights
Monitoring improvements
create_monitornow lists all 15 supported metrics (roas, ctr, cpc, cpa, cpm, cpv, spend, conversions, impressions, clicks, cost_per_lead, conversion_rate, budget_utilization, video_views, engagement_rate)- Advanced monitoring: AND/OR logic across multiple conditions, consecutive-day triggers, relative thresholds, percentage change detection, campaign-level targeting, and auto-actions (pause campaign, adjust budget)
Meta Ads: ad set parity and custom audience reliability
add_meta_ad_set now supports all campaign-level features
When adding ad sets to existing Meta campaigns, you can now use the same parameters that were previously only available at campaign creation:- Lifetime budgets — set
budget_lifetimeon individual ad sets - End dates — set
end_timeon ad sets (required when using lifetime budgets) - Multi-advertiser opt-out — control
multi_advertiserper ad set - Granular placements — set
publisher_platforms,facebook_positions, andinstagram_positionsper ad set
Custom conversion tracking fix
custom_conversion_id is now properly decomposed into its underlying pixel and event configuration before being sent to Meta. Previously, passing a custom conversion ID could cause a Meta API error on campaign or ad set creation. Adspirer now automatically resolves the conversion via the Meta API and applies the correct pixel ID and event type.list_meta_custom_audiences reliability
- Timeout increased from 30 seconds to 90 seconds — accounts with 1,000+ audiences no longer time out
- Audience status now displays as clean labels (“Active”, “Paused”) instead of raw SDK objects
TikTok Ads: full performance analytics
8 new performance analytics tools bring TikTok to parity with Google and Meta for campaign analysis. Total TikTok tools: 4 → 31.New analytics tools
TikTok now fully available
TikTok Ads is no longer marked “Coming Soon” during onboarding. You can connect your TikTok Ads account directly from the setup flow.TikTok campaign management and creation
19 new tools for full campaign lifecycle management on TikTok — from campaign creation through ad group and ad management, including Spark Ads, Carousel, and APP_PROMOTION support.New campaign management tools (12)
list_tiktok_campaigns— List all campaigns with status, objective, and budgetget_tiktok_campaign_details— Detailed campaign infopause_tiktok_campaign/resume_tiktok_campaign— Control campaign statusupdate_tiktok_campaign— Update name, budget, budget modelist_tiktok_ad_groups/pause_tiktok_ad_group/resume_tiktok_ad_group/update_tiktok_ad_group— Full ad group managementlist_tiktok_ads/pause_tiktok_ad/resume_tiktok_ad— Ad-level management
New campaign creation tools (7)
add_tiktok_ad_group— Add ad groups with full targeting to existing campaignsadd_tiktok_ad— Add ads to existing ad groups (image, video, Spark Ads, Carousel)create_tiktok_carousel_card— Create carousel cards from multiple imagesupload_tiktok_images— Upload images to TikTok Asset Librarysearch_tiktok_targeting— Search interests, keywords, regions, languages, action categories, carriers, and device models
New ad formats
- Spark Ads — Boost existing TikTok organic posts as ads
- Carousel Ads — Multi-image carousel format
- APP_PROMOTION — App install campaign objective with app ID configuration
Campaign Budget Optimization (CBO)
TikTok campaigns now supportbudget_optimize_on for campaign-level budget optimization. TikTok CBO is on by default — set to false to manage budgets per ad group manually.Google Ads fixes
get_campaign_targeting— New tool to view location targeting on existing campaignsget_campaign_structure— Now paginated for large accountsanalyze_search_terms— Newraw_reportmode shows actual search terms users type into Google- Keyword removal now validates IDs before attempting deletion, with per-keyword error reporting
LinkedIn Ads overhaul + Meta Ads gaps closed
LinkedIn campaign hierarchy and targeting
Complete overhaul of LinkedIn campaign tools with campaign group support, rollback logic, and 14 new targeting facets.- Campaign groups —
campaign_group_idandcampaign_group_nameon all create tools. Newadd_linkedin_campaign_to_grouptool for adding campaigns to existing groups. - Carousel creatives — New
add_linkedin_carousel_creativetool - Creative naming —
creative_namefield added to all 4 campaign creation tools - 14 new targeting facets — skills, job functions, interests, degrees, fields of study, employers, groups, age ranges, genders, schools, member behaviors, years of experience, followed companies, and buyer groups. All facets work on both create and update.
- Video discovery — Now finds videos uploaded via LinkedIn Campaign Manager UI, not just API uploads
- Rollback logic — Failed campaigns are automatically archived to prevent duplicates on retry
- Campaign filtering —
list_linkedin_campaignsnow filters by campaign group
Meta Ads: 6 critical gaps
- Lifetime budgets — Set
budget_lifetimeat campaign creation (mutually exclusive with daily budget) - End dates —
end_timesupport on campaigns and ad sets - Custom audiences — New
list_meta_custom_audiencestool for viewing database lists, lookalikes, website, and engagement audiences - Granular placements — Control
publisher_platforms,facebook_positions, andinstagram_positionsat campaign creation - Multi-advertiser opt-out — New
multi_advertiserfield to opt out of Meta’s multi-advertiser ads - Custom conversion tracking — Fixed
custom_conversion_idbeing silently dropped on image and carousel campaigns
Monitoring
- New
delete_monitortool — Previously, deleting monitors required knowing aboutmanage_scheduled_task, which AI clients couldn’t discover
Gemini CLI Extension
Adspirer is now available on the Gemini CLI Extensions Gallery. Google’s terminal-based AI tool can now manage your ad campaigns across all 4 platforms.Install
What’s Included
- MCP Server — 100+ tools across Google Ads, Meta Ads, LinkedIn Ads, and TikTok Ads
- 5 Slash Commands —
/adspirer:setup,/adspirer:performance-review,/adspirer:write-ad-copy,/adspirer:wasted-spend,/adspirer:refresh - OAuth authentication — browser opens automatically on first use
Official Claude Plugin
Adspirer is now an official plugin in the Claude plugin marketplace (claude-plugins-official). Available on both Claude Code and Claude Cowork.What Changed
- No more custom marketplace setup. Previously, you had to manually add the
amekala/ads-mcpmarketplace before installing. Now just search for “adspirer” in the plugin browser. - Claude Code: Type
/plugin, search “adspirer”, and installadspirer-ads-agentdirectly. Or run/plugin install adspirer-ads-agent. - Claude Cowork: Go to Customize → Browse Plugins and search for “adspirer” — install with one click.
- Plugin page: claude.com/plugins/adspirer-ads-agent
What’s Included
The official plugin bundles everything in a single install:- MCP Server — 100+ tools across Google Ads, Meta Ads, LinkedIn Ads, and TikTok Ads
- 5 Slash Commands —
/setup,/performance-review,/write-ad-copy,/wasted-spend,/refresh-brand-context - 2 Skills — Ad campaign management and best practices
- 1 Agent — Performance marketing agent with safety rules
Lead Gen Campaign Support
Full lead generation support across Google Ads and Meta Ads — performance analysis, wasted spend, and audience tools now handle lead gen campaigns correctly.Google Ads Lead Gen
- Performance analysis, wasted spend, and audience tools now work for campaigns optimized for leads. Previously, tools could crash or show incorrect metrics for lead gen campaigns.
- Conversion metrics now use primary conversions only (
metrics.conversions), matching what you see in the Google Ads UI. Previously, Adspirer reported all conversions including secondary actions, which inflated numbers. - PMax search themes now correctly apply to the specified asset group, not the first one found.
Meta Ads Lead Gen
- All performance tools —
analyze_meta_campaign_performance,analyze_meta_ad_performance,get_meta_wasted_spend, and audience analysis — now support lead gen campaigns (OUTCOME_LEADS optimization). - CPA calculation now uses the ad set’s optimization event instead of dividing by total conversions. If you’re optimizing for leads, CPA reflects cost-per-lead, not cost-per-all-actions.
- Audience CPA sort order now shows lowest CPA first for lead gen campaigns.
Audience Search Fix
search_audiencesnow returns results for multi-word queries (e.g., “digital marketing” or “home improvement”). Previously, multi-word searches returned zero results, causing AI clients to fabricate audience IDs.- DemandGen and YouTube tools now validate audience segment IDs against the API instead of accepting AI-generated IDs that don’t exist.
OpenClaw Plugin Fix
Fixed empty-argument bug affecting all 143 tools. The OpenClaw plugin now ships complete input schemas, so tools receive the parameters you provide instead of empty objects.Faster Tool Responses
- Google Ads account list cached in Redis (3-minute TTL) — subsequent tool calls skip the account discovery API call.
- All Google Ads data cache TTLs increased to 10 minutes — repeat queries (e.g., checking campaign performance twice) return instantly from cache.
Google Ads Rate Limit Fix & MCC Reliability
Rate Limit Resolution (P0)
Fixed a critical issue where Google Ads API rate limits (HTTP 429) could block all users — not just the affected account. The system now caches account list responses and includes an emergency recovery endpoint. Users who were seeing “Resource has been exhausted” errors should no longer be affected by other accounts’ API usage.MCC Account Fixes
- Child accounts under MCC (My Client Center) manager accounts now correctly resolve their
login_customer_idduring onboarding and tool calls. Previously, some MCC child accounts would fail with “The caller does not have permission” errors. - Direct (non-MCC) accounts are no longer incorrectly mapped to an MCC manager, which caused “customer not found” errors for users with standalone ad accounts.
login_customer_idis now stored in the database, eliminating aListAccessibleCustomersAPI call on every tool call — faster and more reliable.
Meta Ads CPA Fix
CPA for Meta campaigns now uses the ad set’s optimization event (e.g., cost per lead, cost per purchase) instead of dividing spend by total conversions. This was especially inaccurate for lead gen campaigns where secondary events inflated the denominator.Error Clarity, LinkedIn & Meta Fixes
Google Ads Error Messages
- Centralized error parsing across all 18 Google Ads write operations. Errors now show the specific field and issue (e.g., “headline exceeds 30 characters”) instead of raw API codes.
add_keywordsnow detects policy violations (trademark, restricted content) and provides specific guidance.update_bid_strategyreturns actionable error details when a strategy change fails, instead of just the strategy name.
LinkedIn Improvements
search_linkedin_targetingnow uses LinkedIn’s typeahead API for better, faster targeting search results. Facet names (job title, company, industry) are correctly mapped to LinkedIn’s API format.- Fixed parameter mismatches, null handling, and error parsing across LinkedIn Ads tools.
Meta Ads Fixes
add_meta_adandadd_meta_ad_setnow honor the name you provide. Previously, the user-provided name was silently ignored.add_keywordsrouting fix — calls now use the correct code path with policy violation detection.
OAuth Fix
Fixed a 500 error on the OAuth authorization page. Users connecting via ChatGPT or Claude would see a server error instead of the consent screen.LinkedIn Creatives & Campaign Enhancements
LinkedIn Creatives
- Fixed
list_linkedin_creativesreturning empty results for large accounts (22,000+ creatives). Pagination now handles all account sizes correctly. - Fixed duplicate creatives appearing in results due to pagination overlap.
- Rewrote creative filtering to use LinkedIn’s server-side FINDER API, eliminating timeouts on campaign-level creative lookups.
- Fixed LinkedIn metrics silently dropping to zero, MCP timeout on large result sets, and pagination breaking on no-match scenarios.
Google Ads Campaign Extensions
- Added
MAXIMIZE_CONVERSION_VALUEas a supported bidding strategy for all campaign types. - Extensions (sitelinks, callouts, snippets) are now added in a single batch operation instead of individually, reducing API calls and errors.
- Automatic retry on
CONCURRENT_MODIFICATIONerrors when multiple operations target the same campaign.
PMax, Demand Gen & YouTube
Your business logo is now automatically injected into PMax, Demand Gen, and YouTube campaigns during creation — no need to provide it manually if one exists at the account level.Monitoring
Fixedcreate_monitor using a 30-minute default check interval, which was below the API minimum of 1,440 minutes (24 hours). Monitors now default to a valid interval.Perplexity Computer Support
New AI Client: Perplexity
Adspirer now supports Perplexity as an AI client via MCP connector. Connect Adspirer to Perplexity Computer — the autonomous AI agent — and combine real-time web research with 100+ advertising tools.- OAuth setup — Add Adspirer as a custom connector in Perplexity Computer → Connectors. OAuth auto-discovery means zero configuration beyond the URL.
- Search + ads — Perplexity’s native web search lets you research competitors and market trends, then immediately act on that research using Adspirer tools. No other client combines real-time search with ad management this seamlessly.
- Perplexity Computer — Max subscribers get autonomous multi-step workflows: research → create → optimize, all from a single prompt.
- Requires Perplexity Pro (200/mo), or Enterprise.
Audience Targeting Fixes for Demand Gen, YouTube & PMax
Custom Interest Audiences Now Work in Demand Gen & YouTube
Custom interest audiences (custom segments) were not being applied when creating Demand Gen or YouTube campaigns — even though the tool response showed them as set up. Remarketing audiences worked correctly, but custom interest targeting was silently dropped. This is now fixed. All audience segment types (in-market, affinity, custom audiences, and remarketing lists) work consistently across PMax, Demand Gen, and YouTube campaigns.PMax: No More Unwanted Search Themes on Remarketing Campaigns
When creating a PMax campaign with only remarketing audiences and no search themes, the system was auto-generating search themes from your ad headlines. If you only ask for audience targeting, search themes will no longer be added automatically.Stable MCP Sessions
No More Intermittent “Invalid Token” Errors
Fixed an issue where some tool calls would randomly fail with “Invalid or expired token” — especially after being idle for a while. Sessions are now resilient to Clerk session expiry. If a session token becomes stale, the system automatically recovers without requiring you to reconnect.Billing & Onboarding UX
Billing Page
- Fixed pricing display and plan comparison layout
- Fixed broken navigation between billing sections
- Improved upgrade/downgrade CTA logic
Onboarding
- Fixed layout and scroll issues on onboarding screens
- Plan tier messaging now accurately reflects current pricing
- Save badge visibility fixed
Automation Tools: Multi-Platform Fix
Scheduled briefs, monitoring alerts, and on-demand reports now work correctly for all platforms — Meta Ads, LinkedIn Ads, and TikTok Ads. Previously, automation tools only worked reliably for Google Ads. Monitors set to track “all platforms” were silently resolving to zero accounts.Persistent MCP Sessions & Faster Auth
No More Frequent Reconnects
MCP access tokens now last 1 week instead of 1 hour. Claude, ChatGPT, Codex, and Cursor sessions stay authenticated much longer — no more “Error occurred during tool execution” after stepping away for an hour.Diagnostic tools (get_usage_status, get_connections_status) remain available even when your quota is exhausted, so you can always check your account status.Faster Tool Responses
Added an in-process auth cache that eliminates repeated token verification overhead. Subsequent tool calls in the same session resolve authentication instantly instead of re-verifying on every request.Manus AI Client Support
New setup guide for connecting Adspirer to Manus — the autonomous AI agent. Manus connects via API key authentication with Streamable HTTP transport. Import Adspirer skills directly from GitHub for campaign management workflows.Meta Ads Fix
Meta tools now always pass the correct connected ad account ID. Previously, some Meta tools could fail with “No ad account found” even when an account was connected.LinkedIn Ads Fix
Fixed currency formatting for LinkedIn campaign metrics. Campaigns with non-USD currencies now display correctly instead of showing raw API values.Faster Google Ads Account Loading
Google Ads account connections now load with lazy pagination and parallel processing. The connections page loads instantly instead of waiting for all accounts to resolve.Quota Experience & Error Clarity
Completely overhauled how Adspirer communicates quota limits and errors across all AI clients.Usage Warnings Before You Hit the Wall
Tool responses now include a visible usage footer when you’re approaching your quota limit:- 75%+ usage —
📊 12/15 free calls used (80%) — 3 remaining. Upgrade: ... - 90%+ usage —
🚨 2 calls remaining! Upgrade now to avoid interruption: ...
Diagnostic Tools Always Available
get_usage_status, get_connections_status, and echo_test now work even when your quota is exhausted. You can always check your usage and connection status regardless of your remaining calls. These tools don’t count against your quota.Clear Error Messages
- Quota exceeded — shows a clean upgrade message with pricing and payment link (previously showed a generic “Error occurred during tool execution” on Claude)
- Session expired — now tells you exactly what happened and how to reconnect (previously showed the same generic error)
- Server errors — include the actual error details and retry guidance
Demand Gen: Multi-Region Ad Groups
Add ad groups to existing Demand Gen campaigns withadd_demandgen_ad_group:- Each ad group can target different locations (e.g., US cities vs India cities vs UAE cities)
- Each ad group can have its own audience signals (in-market + affinity segments)
- Reuse existing account images and YouTube videos across ad groups
- Different creative variations per ad group
Meta Ads: City Targeting & Placement Creatives
- City-level targeting — target specific cities in Meta campaigns with
search_meta_targeting - Placement-specific creatives — upload different images for Feed, Stories, and Reels placements
- Emoji support — use emoji in Meta ad headlines and descriptions
AI Client Input Resilience
Adspirer now handles common input mistakes from AI clients automatically:- JSON strings sent as text instead of objects are auto-parsed
- Integer IDs sent instead of strings are auto-coerced
- Extra whitespace and unknown fields are silently handled
- Works across all 100+ tools — no more validation errors from formatting issues
PMax: Multiple Asset Groups & Bidding Control
- Multiple asset groups per campaign — create campaigns with distinct asset groups for different product lines or audiences
- Bidding strategy control — your explicit bidding choice (Maximize Conversions, Target ROAS, etc.) is now always honored
- Auto-derived search themes — search themes are automatically suggested from your headlines and descriptions
- Post-creation nudge — after creating a PMax campaign, you’re prompted to add search themes and audience signals
Demand Gen Campaign Creation
Full support for Google Demand Gen campaigns — reach users across YouTube, Discover, Gmail, Display, and Maps from a single campaign.Create Demand Gen campaigns withcreate_demandgen_campaign:- Multi-asset format — landscape, square, and portrait images with headlines and descriptions
- Video responsive format — YouTube videos with text overlays
- Automatic sitelink, callout, and structured snippet extensions
- Location and language targeting at the campaign level
- All bidding strategies supported: Maximize Clicks, Maximize Conversions, Target CPA, Target ROAS
Audience Targeting
- In-market and affinity audience segments via
search_audiences - Reuse existing audiences from Google Ads UI
- Per-ad-group audience customization
Meta Ads Fixes
- Fixed lead form handling for OUTCOME_LEADS and OUTCOME_ENGAGEMENT campaigns
- Fixed Meta page and Instagram account lookup for business accounts
- Wasted spend analysis now respects learning phase and minimum spend thresholds
PMax Search Themes & Audience Signals
Added 7 new tools for managing search themes and audience signals on Google Ads Performance Max campaigns. These PMax-only features give you direct control over how Google’s automation targets search queries and audience segments.New Tools
Search Themes
Short phrases (max 50 per asset group) that tell Google which search queries your PMax campaign should target. They supplement Google’s automated targeting with explicit intent signals. Supports add and remove operations — to update, remove and re-add.Audience Signals
Tell Google which audience segments are most likely to convert. Combine multiple segment types in a single signal:- In-market audiences — users actively researching products in a category
- Affinity audiences — users with sustained interests and habits
- Custom audiences — account-level custom audience segments
- User lists — first-party data (website visitors, customer lists, CRM uploads)
Agent Skills Updated
The Ad Campaign Management skill and Performance Marketing Agent now include search themes and audience signals in the PMax campaign creation workflow (steps 9-10). The agent will automatically recommend search themes based on keyword research and suggest relevant audience segments.Bug Fixes
- Fixed GAQL query syntax for asset group signals (
campaign.idinstead ofasset_group.campaign.id) - Fixed audience search returning zero results (replaced case-sensitive GAQL LIKE with client-side filtering +
taxonomy_typeenum) - Added
user_list_idssupport for remarketing lists in audience signals - Increased max search themes from 25 to 50 (Google’s actual limit)
API Key Authentication (Personal Access Tokens)
Adspirer now supports Personal Access Tokens for headless and remote server authentication. Generate API keys from the dashboard and use them on remote servers, Docker containers, and CI/CD pipelines where browser-based OAuth isn’t available.What’s New
- API Key Management UI — Generate, name, and revoke API keys from adspirer.ai/keys
- OpenClaw
--tokenflag —openclaw adspirer login --token sk_live_...for headless authentication ADSPIRER_API_KEYenv var — Set the environment variable for zero-config server authentication- Tier-based key limits — Free: 2 keys, Plus: 5, Pro: 10, Max: 20
- Key expiration — Optional expiration (30 days, 90 days, 1 year, or never)
- Admin controls — Admin dashboard for API key analytics, per-user key management, and emergency revocation
- Auth method tracking — Tool call logs now track whether each call used OAuth or an API key
Security
- Keys use
sk_live_prefix for easy identification - SHA-256 hashed storage — raw tokens never stored server-side
- Instant revocation with audit trail
- Keys cannot be used to create other keys (prevents privilege escalation)
Documentation
- OpenClaw Remote Server Setup — Step-by-step guide
- Security — API Key Authentication — Security model and comparison
- Updated How MCP Works — Authentication section
- Updated FAQ — Remote server and API key questions
Claude Cowork Setup Guide
New documentation page with step-by-step visual guide for connecting Adspirer to Claude Cowork. Includes 9 annotated screenshots covering the full flow: plugin install from marketplace, connector setup, OAuth authentication, and brand folder workspace.Claude Connector Simplified
Claude Chat setup no longer requires manual OAuth configuration. Just paste the URL — Claude auto-discovers the server name and authentication settings.ChatGPT Setup Updated
ChatGPT setup updated to match current UI: new field names, OAuth advanced settings callout, “I understand and want to continue” checkbox, and the new Reference memories and chats preferences screen.LinkedIn Exhaustive Campaign Features
Extended LinkedIn campaign tools with exhaustive targeting and management capabilities. Fixed Googlelist_campaign_extensions returning incorrect data.Database Performance
Phase 1 database performance improvements for faster query execution across campaign metrics and user analytics.Documentation: Agent Pages & Support
Added 8 new documentation pages:- Claude Code Agent, Cursor Agent, Codex Agent, OpenClaw Agent — per-client agent architecture docs
- How It Works — 5-layer architecture page
- FAQ, Glossary, Support — knowledge base expansion
- Added Support tab to top navigation
Pricing V2
Updated pricing across all tiers:- Annual pricing option now available with savings
- Tool call counter resets to 0 on tier upgrade
- Fixed subscription cancellation on upgrade to prevent double-billing
- Stripe webhook handlers now sync quota correctly
MCC/Manager Account Warnings
Connections page now warns users attempting to connect MCC (Google) or Business Manager (Meta) accounts instead of individual ad accounts.OpenClaw Plugin Updates
openclaw adspirer uninstallCLI command added- OAuth retry logic improved
- Skill metadata updated with security section and privacy policy
Skill Reference & Performance Marketing Agent Docs
Added 2 new pages to the Agent Skills section:- Skill Reference — Complete reference for all 5 Adspirer skills with invocation commands per IDE (Claude Code, Cursor, Codex), step-by-step execution details, and example prompts
- Performance Marketing Agent — How the agent orchestrates skills with brand knowledge, strategy persistence, and memory across sessions
Strategy-Aware Execution
Skills now readSTRATEGY.md before executing — a persistent file where strategic decisions (AVOID, PREFER, CONSTRAINT, REQUIRE directives) survive across sessions:- Campaign creation loads strategy directives at Step 0 and flags conflicts with research results
- Keyword research cross-references results against AVOID/PREFER directives
- Performance review flags “Strategy Drift” when campaigns violate active directives
- Wasted spend prioritizes campaigns violating strategy as waste sources
Agent Documentation Highlights
- Mermaid architecture diagram showing Agent → Context + Strategy + Memory → Skills → Tools → Platforms
- IDE comparison table for agent features across Claude Code, Cursor, and Codex
- Brand Workspace setup flow and context file structure
- Cursor Rules and Codex Safety Rules explained with before/after examples
Asset Discovery & PMax Validation
- Fixed asset discovery across platforms
- YouTube logo upload support for PMax campaigns
- Mandatory extensions enforcement for Google Ads
- PMax logo validation improvements
CLI OAuth Fix
Resolved OAuth failures for CLI clients (Claude Code, Codex). Loopback redirect now correctly routes web vs CLI authentication flows.Cross-Domain Attribution
Added referrer-based UTM fallback for cross-domain tracking between adspirer.com and adspirer.ai.Help & Contact Page
Added in-app Help page with documentation link and contact options.YouTube Ads Campaign Support
Added YouTube Ads campaign creation to the Google Ads toolset. Create video ad campaigns targeting YouTube viewers with budget controls and audience targeting.Automation Tools
Launched 8 automation tools:- Scheduled briefs — automated performance summaries on a recurring schedule
- Performance monitors — alerts when campaigns cross KPI thresholds
- Cross-platform reports — unified reporting across Google, Meta, and LinkedIn
UI Redesign
Mobile dropdown and desktop tab redesign for the main app. Removed trial language from onboarding flow.Documentation Updates
- Enhanced Mintlify components: Frame, Badge, Check, Info, Tooltip across all pages
- Tabbed install methods for Claude Code setup
- Resend-style navbar redesign
- GA4 tracking added to docs site
- 6 new Knowledge Base articles, MCP explainer page, Mermaid workflow diagrams
- UTM tracking on all CTA links
Documentation Site Launch
Launched comprehensive documentation at adspirer.com/docs with 24 pages covering all AI clients, ad platforms, agent skills, and in-depth guides.- AI client guides for ChatGPT, Claude, Claude Code, Cursor, Codex, OpenClaw, and Windsurf
- Ad platform guides for Google Ads (39 tools), Meta Ads (20 tools), LinkedIn Ads (28 tools), and TikTok Ads (4 tools)
- Agent skills documentation with workflows, tool catalog, and safety rules
- 7 in-depth guides covering keyword research, automation, and strategy
- Auto-generated
llms.txt,llms-full.txt, andskill.mdfor AI agent discovery - Contextual sharing to ChatGPT, Claude, Cursor, and VS Code
ChatGPT MCP Connector
Added native MCP connector support for ChatGPT Plus and Pro users. Connect Adspirer directly in ChatGPT Settings with OAuth 2.1 authentication.Claude MCP Connector
Added native MCP connector for Claude Pro, Max, Team, and Enterprise. Includes progress streaming for real-time updates during campaign creation.Codex Agent Support
Added autonomous agent setup for OpenAI Codex with YAML configuration and skill files.OpenClaw Plugin
Released zero-configuration OpenClaw plugin with bundled 14.4KB skill file. Install withopenclaw plugins install openclaw-adspirer.ChatGPT MCP Connector Fix
Fixed dynamic client registration to correctly detect Claude vs ChatGPT during OAuth. Claude clients now receive the correct redirect URIs instead of ChatGPT credentials.OpenAI Apps SDK Integration
Added domain verification, OAuth protected resource endpoints, MCP annotations for tool hints, and OpenAI Platform redirect URI for app submission.LinkedIn Campaign Fixes
Fixed LinkedIn campaign creation and update workflows. Resolved API version errors.Conversion Tracking
Set up end-to-end conversion tracking infrastructure for measuring signup-to-paid funnel. Multiple fixes to Google Ads metrics accuracy.Onboarding Revamp
Redesigned onboarding flow with mobile-responsive screens, auto-completion logic, and MCP OAuth gating to prevent onboarding bypass.Enterprise Readiness
Account lifecycle management, metrics pause for inactive accounts, and sign-in/sign-up page revamp.Meta Ads Traffic Management
Added Meta video and carousel campaign creation, ad management workflows, and traffic management tools.GTM Cross-Domain Tracking
Added Google Tag Manager (GTM-PQGBFK5Q) to frontend. GA4 sessions now persist across domains via the_gl parameter.LinkedIn Ads Full Integration
Complete LinkedIn Ads integration across 8 phases:- LinkedIn account setup and OAuth
- Single image sponsored content campaigns
- Campaign performance analytics
- Unified tools for cross-platform management
Meta Video & Carousel Campaigns
Added video campaign creation and carousel ad support for Meta Ads.Local Currency Support
Fixed currency handling across all MCP tools and backend APIs. Campaigns now display metrics in the user’s local currency.Smart Metric Collection
Automated background metric collection for historical performance tracking.Asset Reuse & PMax Improvements
- Smart asset discovery and reuse for Performance Max campaigns
- Domain filtering for sitelinks
- Location targeting fix for MCP/ADK PMax campaigns
Account Tier System
Account tier infrastructure with 120-day metric backfill for new users. Accurate daily metrics viasegments.date in queries.ChatGPT Apps SDK Widgets
In-app quota widget and account management tools for ChatGPT users. OAuth improvements for API routes.Custom GPT Support
Added ChatGPT Actions support with OAuth compatibility for Custom GPT configurations.MCP Protocol Improvements
- Progress streaming (MCP 2025-03-26) for real-time updates during campaign creation
- False success message elimination
- OAuth token rotation on reconnect
- JWT expiry fix and performance routing improvements
TikTok Ads Integration
Complete TikTok Ads platform integration:- OAuth setup and multi-platform architecture
- In-feed video campaign creation
- Image upload and asset validation
- Session handling and location targeting
MCP Server Launch
Initial MCP server deployment atmcp.adspirer.com:- OAuth 2.1 with PKCE authentication
- Complete PMax campaign creation via ChatGPT
- Modular architecture for multi-platform support
Creative Canvas
Multi-image upload UX improvements and character limit enforcement for PMax campaigns.Adspirer Launch
Initial release with 100+ tools across Google Ads and Meta Ads.Google Ads (39 tools)
- Keyword research with real CPC data from Google Keyword Planner
- Search and Performance Max campaign creation
- Wasted spend analysis, budget optimization, and ad extensions
- Asset discovery, validation, and ad copy generation
Meta Ads (20 tools)
- Image, video, and carousel campaign creation
- Audience targeting and creative fatigue detection
- Placement optimization and performance analysis
Core Features
- OAuth 2.1 authentication with PKCE
- Multi-platform account management
- Agent skills system with SKILL.md instruction files

