Four beta integrations. Every other status, named.
Google Ads, GA4, Merchant Center and Search Console are available to controlled-beta customers. Meta is reviewer-only, Shopify accepts no new public installs during review, and TikTok Ads remains a supervised test path. The implementation details below do not turn those limits into customer availability.
No card to connect. Every connection is read-only until you turn writes on, per account.
Not a demo: the same status words as the matrix below.
Section 01 · where each platform stands
Seven platforms, and six we have not built.
Six states for the platforms we have built, one for the platforms we have not, and no eighth. There is no coming-soon badge on this page, because a badge without a date is a promise we would be making with your money on the table. Read the status column before the two on its right: a platform whose code is finished says exactly that and nothing more, until production has evidenced the rest.
| Platform | Status | What Mako reads | What Mako can change, only after you approve |
|---|---|---|---|
| Meta Ads | Reviewer-only · app review in progress | Ad accounts, campaigns, ad sets, ads and creative thumbnails, plus spend, impressions, clicks, CTR, CPC, CPM, frequency, reach, purchase ROAS and purchase actions, day by day | Three changes: pause or activate a campaign, set a campaign daily budget, move daily budget between two campaigns or two ad sets |
| Google Ads | Controlled beta · production evidence pending | Campaigns, exact budget identity, period, sharing state and complete bounded linked-campaign sets, experiments with control/treatment splits and Google-reported uncertainty, ad groups, keywords, search terms, responsive search ad text and policy status, existing campaign and ad-group asset links, complete bounded Shopping product-group trees, plus cost, impressions, clicks, conversions and conversion value, day by day | Thirty-five changes across thirty-two separately gated families: pause 2–10 exact enabled campaigns in one atomic batch, end one exact running experiment without promoting its treatment, permanently dismiss one exact Google-native recommendation without applying it, pause, enable, rename or permanently remove one already-paused campaign, create or change one operational label relationship, attach, pause, enable or remove one existing campaign or ad-group asset relationship, create one advertiser-authored account-level callout, create one detached call asset, create one detached Google-hosted lead form, change one existing Performance Max asset group’s name, status, HTTPS destinations or display paths, add or remove one Performance Max search-theme or existing-audience signal, include or exclude one existing non-root Performance Max or Standard Shopping product-group leaf or change one eligible Manual CPC product-group bid, set a non-shared campaign daily budget, change one existing shared daily budget’s amount or name or one eligible campaign total budget, change Search Partners, exact campaign dates or tracking, country, region, radius or language targeting, demographic exclusions, device modifiers, complete schedules or placement exclusions, set or clear one exact target CPA or target ROAS on an existing eligible standard or portfolio strategy, include or exclude one exact campaign conversion goal or restore account defaults, create one exact secondary website or call conversion action and return Google’s code for installation, replace complete reviewed content on one paused responsive search ad, create a paused campaign, add or remove campaign negatives, manage positive ad-group keywords, pause, enable or rename an ad group, create or remove a paused Search ad group, change its Manual CPC bid or manage an exact existing audience link and mode, change a keyword bid, HTTPS destinations or match type, change location-presence mode, pause or enable one existing ad, and permanently remove one already-paused ad. Every family is off by default and requires workspace admission before its own account switch and exact approval can matter. |
| Google Merchant Center | Controlled beta · production evidence pending | Your Merchant Center accounts, the data sources in them, and every product with its item-level issues and per-country approval status | One change: publish the product feed Sable Mako builds from your Shopify catalog, which makes us the primary data source for that account |
| TikTok Ads | Supervised validation · not customer available | Advertiser accounts with currency and timezone, plus spend, impressions, clicks, conversions and TikTok's own attributed purchase value, by day, at account and campaign level | Nothing today. Campaign creation, one card that builds a campaign, ad group and ad all paused, is written and switched off: three separate things hold it off, and any one of them alone would be enough |
| Shopify | Existing installs only · app review in progress | Shop name, domain, currency, plan and timezone; daily gross sales, discounts, returns, net sales, total sales and order count; product count; order count and a sampled revenue total for a window | Nothing. Shopify is read-only today: no write permission is requested and no write path exists in the code |
| Google Analytics 4 | Controlled beta · production evidence pending | Sessions, key events, purchases and revenue by traffic source and medium, day by day, plus the same window rolled up by channel group | Nothing. The permission we request is read-only |
| Google Search Console | Controlled beta · production evidence pending | Search queries and pages, with clicks and impressions by day, plus the list of your verified sites at connect time | Nothing. The permission we request is read-only |
| Six more platforms | Not built | Nothing | Nothing |
In full: LinkedIn Ads, Microsoft Ads, Pinterest Ads, Snapchat Ads, Klaviyo, Amazon Ads. Section 04 says what not built means, and it is stricter than it sounds.
Section 02 · the two switches
Two switches stand between Mako and your account.
Writes are off when a connection is created.
Every connection is stored with write access off. While it is off, the change tools are left out of the request we send to the model, so the agent cannot emit a change even if you ask it to.
You turn writes on per account, and confirm it.
The switch lives on that one connection. Arming Meta never arms Google. Turning it on takes a confirmation and turning it off does not, and the code refuses to arm it at all for TikTok Ads, Shopify, GA4 and Search Console.
Every single change still needs its own approval.
The agent writes a proposal rather than a change. You see the current value, the proposed value, the numbers behind it and any warnings our server computed, above the approve button.
A proposal older than 24 hours will not execute and has to be asked for again. A double-click cannot execute it twice. After a change runs, Mako re-reads the platform in the same request and reports success only when the platform's own value matches what you approved. A mismatch is stored as a failed verification and shown to you as one.
The refusals, the audit record and the exact bounds are on the security page.
Section 03 · every field, per platform
Every field we ask for, one platform at a time.
Meta Ads
Why it is here. The account Mako audits, watches daily, and can be authorised to adjust.
Permissions we request:
ads_readads_managementbusiness_managementpages_show_listpages_read_engagementWhere the connection runs through Facebook Login for Business, our authorize request omits the permission list entirely and the granted set comes from a configuration inside our Meta app rather than from our code. Meta's own consent screen shows you the permission set you are actually granting, and that screen is the authority.
What we read
- Which ad accounts your login can reach: account id, name, currency, account status, the business that owns it, and lifetime amount spent
- Account summary: name, currency, status, lifetime amount spent, business name and timezone
- Campaigns: id, name, status, effective status, objective, daily budget, lifetime budget and start time
- Performance at account, campaign, ad set and ad level: spend, impressions, clicks, CTR, CPC, CPM, frequency, reach, purchase ROAS, actions, action values and cost per action
- The same figures broken out by day, which is the history the daily watch compares against
- Ads and creative: name, status, effective status, and the creative's id, name, thumbnail URL, image URL and Instagram permalink
- The state of a campaign or ad set immediately before a change, and again immediately after, to verify it
What can change, after you approve it
- Pause or activate a campaign.
- Set a campaign daily budget. Campaign-level budgets only, so a campaign whose budget lives on its ad sets is refused, and so is one on a lifetime budget.
- Move daily budget between two campaigns, or between two ad sets, inside one account, with the total held constant.
What we never touch: Creating or deleting campaigns, ad sets or ads. Uploading creative. Targeting, bidding, schedules and objectives. Lifetime budgets. Account settings. The Conversions API and your pixel. Pages, posts and audiences.
Guardrails, enforced in code
- A budget increase over 300%, which is more than four times the current figure, is blocked before an approval card is ever created
- A budget change over 20% in either direction shows a warning above the approve button, because it can restart Meta's learning
- A rebalance across two different accounts is blocked and fails closed
- A rebalance cannot take the source down to zero. Pausing is a separate, explicit action
- A campaign covered by a lock rule you wrote cannot be paused, and the refusal quotes your rule back to you
Where this stands today. Meta reads and guarded write code exist, but Meta's app review is still in progress. New grants are limited to Meta reviewers and explicitly allowlisted supervised test accounts. Meta is not part of the ordinary beta offer, and its implemented write tools are not a general availability claim.
Google Ads
Why it is here. Search, where the money leaks one query at a time.
Permissions we request:
https://www.googleapis.com/auth/adwordsGoogle publishes one Ads permission and it covers reading and writing. There is no read-only version to ask for, so read-only is a behaviour we enforce rather than a permission we request: the write switch on your connection starts off, and while it is off the change tools are not sent to the model.
Google can carry forward scopes you granted to the same OAuth client in an earlier consent. We store the set Google reports back rather than the set we asked for, so our own record never understates what a stored credential can do. Search Console is closed and its scope is not requested by the product.
What we read
- The accounts your login can reach, with name, currency and status
- Campaigns: id, name, status, channel type, exact budget id and name, daily or total period and amount, and sharing state
- One exact campaign budget with its complete linked-campaign set, up to 100 campaigns; a larger set is refused rather than called complete
- Campaign performance: cost, impressions, clicks, conversions and conversion value, plus the same series by day
- Active Google Ads experiments: exact experiment and arm identities, traffic split, treatment and control metrics, and Google-supplied point estimates, margins of error and p-values. Missing performance stays unknown, and no winner is selected automatically
- Ad groups: id, name, status and the campaign they belong to
- Keywords: text, match type, status, cost, clicks, impressions and conversions
- Search terms: the term, the keyword that matched it, cost, clicks and conversions
- Responsive search ads: headlines, descriptions, final URLs and policy approval status
- Existing campaign and ad-group asset relationships, plus bounded asset content needed to review an exact proposed link change
- Complete product-group trees for one Performance Max asset group or Standard Shopping ad group, up to 200 nodes, including inclusion state and eligible direct CPC bids
- The negative keywords already on a campaign, so a proposal does not duplicate one
- Campaign and budget state before and after a change, to verify it
Reads stop after 5 pages, and at between 50 and 200 rows depending on the report. When a read is cut short we label it truncated rather than presenting a partial list as the whole account.
What can change, after you approve it
- Supervised rollout, off by default: pause 2–10 exact currently enabled campaigns in one account. The user must name every campaign by exact ID or full name. One approval shows the complete set and always requires a second confirmation. Google validates and receives one all-or-nothing request with partial success disabled; every campaign is re-read afterward. Bulk enable, budget, targeting and mixed-operation batches are not implemented, and restoring campaigns requires separate reviewed approvals.
- Supervised rollout, off by default: end one exact currently running Google Ads experiment. The approval binds the complete experiment, arm, traffic-split and attached-campaign state, requires a second confirmation, validates with Google, checks for drift twice and sends one non-retried end request. Treatment delivery stops immediately; treatment settings are not promoted, no winner is chosen and Sable Mako provides no one-click undo. Experiment creation, scheduling, promotion and graduation are not implemented.
- Pause or enable a campaign.
- Permanently remove one exact already-paused campaign. The campaign and its budget identity are bound to the card, checked before and after Google validation, removed once and re-read. An uncertain response is never replayed, and Google cannot restore the campaign ID, history or learning state.
- Create and attach one operational label, attach one existing label or remove one label relationship from one exact campaign, ad group, ad or positive keyword. This metadata-only family is off by default and re-reads the target and complete attached-label list before an atomic write.
- Supervised rollout, off by default: attach, pause, enable or remove one existing asset relationship on one exact campaign or ad group. Supported links are sitelinks, callouts, structured snippets, calls, lead forms, prices, promotions, apps, images and hotel callouts, plus applicable campaign-level Business Name and Logo links. The target, asset content and current relationship are re-read before Google validates and receives one request. Account-level links other than the separate callout-creation family, location asset sets, asset creation beyond the separate callout, call and lead-form families, asset editing, and Performance Max asset-group assets are excluded. Production provider acceptance is still pending.
- Supervised rollout, off by default: change the name, enabled or paused status, HTTPS destinations or display paths of one existing Performance Max asset group. The exact campaign, daily budget, currency, asset group and current settings are bound to the card and checked twice around Google validation before one update. Creative assets, asset links, audience signals, product groups, URL expansion, campaign budget and bidding remain unchanged by this operation. Saved settings are re-read immediately; serving and policy status can change later.
- Supervised rollout, off by default: add or remove one search-theme or existing-audience signal on one exact Performance Max asset group. The complete signal set and exact campaign, account and asset group are bound to the card and checked twice around Google validation before one mutation. Signals guide Google’s optimization; they do not restrict targeting or delivery to the named theme or audience. Audience creation, Customer Match uploads, creative, product groups, URL expansion, campaign budget and bidding remain unchanged by this operation.
- Supervised rollout, off by default: include or exclude one existing non-root leaf in a complete Performance Max or Standard Shopping product-group tree, or change one existing included Manual CPC Shopping leaf’s direct bid. The card binds the whole tree, account, campaign, container, currency and exact leaf. Google validates; the tree is re-read for drift before one atomic request and again to verify the result. Trees over 200 nodes, roots, subdivisions, shared-budget Shopping campaigns, arbitrary tree construction and Merchant Center item creation are refused. Production provider acceptance is still pending.
- Rename one existing campaign. The approval binds its exact current name and status, refuses drift, and re-reads the result. Delivery, budget and targeting are unchanged.
- Supervised rollout, off by default. Turn Search Partners on or off for one existing Search campaign with a confirmed daily budget, after an explicit request and exact approval. Enabling a shared-budget campaign is refused. Google Search itself, Display, budget and bidding settings are unchanged.
- Change exact campaign dates or tracking settings, with a separate release gate off by default. Dates and tracking are separate approval cards. Account-local whole days only, no shared-budget date changes, bounded tracking fields and ValueTrack macros. Verification checks saved settings, not click paths or analytics results.
- Change one exact campaign targeting or delivery control behind a separate release gate off by default: country, named region, radius or language targets; demographic exclusions; device bid modifiers; the complete account-time-zone schedule; or placement exclusions. Country and language operations use up to 10 reviewed codes. Regions resolve through Google from an exact name and country code or an exact geo target id, and radii bind coordinates, distance and units. Shared-budget campaigns and removal of the last positive location or language are refused. Audience links use the separate ad-group family.
- Set or clear one exact target CPA or target ROAS, or switch one eligible campaign between standard Maximize Conversions and Maximize Conversion Value, behind a separate release gate off by default. A strategy switch also binds the complete conversion-goal map and enabled primary actions. Shared portfolio strategies, shared budgets, unsupported campaign types, drafts and experiments are refused. The exact strategy, target, currency and budget are bound to the card; Google validates and re-reads the result.
- Set or clear one exact target CPA or target ROAS on an existing eligible portfolio strategy, behind the same default-off release gate. The card binds the strategy and every linked campaign, counts shared budgets once and shows the combined daily ceiling. Google validates, checks the whole set again, sends once and re-reads the result. A fresh approval is required to restore the prior target.
- Set a non-shared campaign daily budget. A shared budget is refused in this path because changing it would move money in campaigns the card does not name.
- Supervised rollout, off by default: change one existing shared daily budget’s amount or name, or one eligible campaign total budget. The card binds the exact budget, currency and complete linked-campaign set. Google validates, the state is checked again, one budget field is sent, and the budget plus every linked campaign are re-read. It never creates, assigns, unassigns, unshares or removes a budget. Portfolio-strategy-aligned budgets and experiments are refused. Undo needs another approval and cannot recover spend or learning effects.
- Supervised rollout, off by default: permanently dismiss one exact Google-native recommendation after a separate approval. The card binds Google’s current recommendation ID, type, affected resources and impact estimate; the suggestion is re-read before one non-retried dismissal and afterward for verification. Dismissal does not alter campaign delivery and Google provides no undo. Applying a suggestion is never delegated to Google’s generic apply endpoint: any supported campaign change must use its own Sable Mako approval family.
- Supervised rollout, off by default: include or exclude one exact category-and-origin conversion goal for one campaign, or restore that campaign to the account’s current defaults. The complete goal map and backing conversion actions are checked twice. Custom goals, experiments, incomplete reads and a result with no enabled primary bidding signal are refused. This goal tool does not create or edit conversion actions, tags, attribution or account-wide defaults. Every approval requires a second confirmation.
- Supervised rollout, off by default: create one exact secondary website page-load, website-click, mobile click-to-call or website-call conversion action. The conversion owner and complete current inventory are bound and checked twice. Google validates before the approval is stored and again before one non-retried creation. The verified receipt returns Google’s code but does not claim it is installed or firing. Editing or removing actions, making one primary, changing goals or attribution and altering account defaults are not supported here.
- Supervised rollout, off by default: create one exact 1–25-character advertiser-authored callout and link it at account level. The complete bounded account-callout inventory is checked twice, Google validates the exact atomic request, and a second confirmation is required before one non-retried creation. The receipt verifies the exact marked asset and account link. Google may still review or limit it, and this tool cannot edit or delete the underlying asset.
- Supervised rollout, off by default: create one exact call asset for a named Search campaign after Google validates its eligibility. The card binds the country code, phone number, account-level reporting choice and complete business hours in the account time zone. A second confirmation is required before one non-retried creation. The new immutable asset is verified and remains detached; attaching it needs a separate approval. Replacing a number creates a new asset and leaves the old one unchanged.
- Supervised rollout, off by default: create one exact Google-hosted lead form for a named Search or Performance Max campaign after Google validates its eligibility. The card binds every visible sentence, requested field, HTTPS privacy policy, post-submit destination and four advertiser policy attestations. A second confirmation is required before one non-retried creation. The verified form remains detached; attaching it needs a separate approval. Leads stay available through Google-hosted download and are not delivered to or stored by Sable Mako.
- Create a new campaign, paused, with its budget, targeting, ad groups, keywords, copy and images in one card. Released in Production for admitted workspaces. Approval creates the campaign PAUSED, so it spends nothing until you approve activation separately.
- Add between 1 and 20 negative keywords to a campaign, as exact, phrase or broad, defaulting to exact. Every term shows on the card with its match type before you approve.
- Remove between 1 and 20 existing campaign negative keywords. Exact text, match type and Google's live criterion id are checked again before the write.
- Add, pause, enable or remove between 1 and 20 positive keywords in one ad group. Existing criteria are bound to Google's live ids, and every result is re-read after execution.
- Pause, enable or rename one existing ad group. The approval binds its exact live name and status, refuses drift, enforces caps when enabling, and re-reads the result.
- Supervised rollout, off by default: create or remove one paused Search ad group, change its Manual CPC bid, or add, exclude, remove or change the mode of one exact existing user-list audience link. Exact approval, Google validation and result verification are required. Removal is permanent. Audience creation, Customer Match uploads and Google’s wider audience taxonomy are not supported.
- Supervised rollout, off by default: change one Search campaign between presence-only and presence-or-interest targeting. Exact approval, locks, caps, validation and verification are required. Countries, languages and exclusions stay unchanged.
- Supervised rollout, off by default: create one paused responsive search ad in an existing standard Search ad group after reviewing all copy and destinations. One exact validation-and-create run passed in an isolated Preview; the family is not active in Production. Enabling requires another approval.
- Supervised rollout, off by default: change one keyword’s Manual CPC bid or HTTPS destinations, or replace its match type. Exact approval, current locks and caps, Google validation and result verification are required. Match-type replacement creates the new criterion and removes the old one atomically, refuses criteria with labels or customizers, and cannot preserve the old criterion id or learning state.
- Pause or enable one exact existing ad. The approval binds the ad, its ad group and its campaign, refuses drift, enforces caps when enabling, and re-reads the result. This status operation leaves content unchanged.
- Supervised rollout, off by default: permanently remove one exact already-paused ad. The ad and both parents are bound to the card and rechecked before the one removal request. The same ad id and learning state cannot be restored; interrupted responses are reconciled by reading and never by replaying the removal.
- Replace the complete reviewed headlines, descriptions, pins, HTTPS final URLs and display paths of one paused responsive search ad, behind a separate release gate off by default. Google validates, the exact ad and parent state are checked again, and content is re-read. The ad stays paused and may re-enter policy review.
What we never touch: Image, video or non-responsive-search creative, and content changes to enabled ads. Arbitrary Shopping tree creation or rebuilding, and bidding strategy types. Deleting campaigns or enabled ads. Conversion action settings. Budget sharing. Billing.
Guardrails, enforced in code
- The same 300% block and 20% warning as Meta
- A shared budget is blocked in the single-campaign budget path. The separate shared-budget family is off by default, names every affected campaign and checks them again before one field is sent
- A change has to resolve to exactly one connected Google account. If it is ambiguous, Mako stops and asks
- There is no budget rebalance on Google Ads, and the agent is instructed to say so rather than fake one with two separate writes
Where this stands today. Google Ads is the controlled-beta integration. Its deterministic catalog contains twenty-one rules; twelve apply to ecommerce workspaces and twelve to service workspaces. The connector and audit have Production read evidence. Campaign status, campaign name and one private daily-budget path have supervised Production write-and-inverse evidence. Every action family remains separately gated by workspace, and Settings shows which families, if any, are released. Exact approval remains mandatory; the other families still need provider acceptance before release.
Google Merchant Center
Why it is here. The product feed behind Shopping, where a bad title costs every impression.
Permissions we request:
https://www.googleapis.com/auth/contentGoogle publishes one Merchant Center permission and it covers reading and writing, the same as Ads. There is no read-only version to ask for, so read-only is a behaviour we enforce rather than a permission we request: publishing starts off on your connection, and while it is off no publish tool is sent to the model and the server refuses a publish even if one were proposed.
What we read
- The Merchant Center accounts your login can reach, with their names
- The data sources in an account, so we adopt an existing feed rather than creating a second
- Products already in the account, with their offer ids and attributes
- Item-level issues and per-country approval status, which is what the feed audit reports
- The same product list again after a publish, to confirm what was accepted
Product reads stop after 5 pages of 250. When a read is cut short we label it truncated rather than presenting a partial catalog as the whole account.
What can change, after you approve it
- Publish the built feed. The first publish makes Sable Mako the PRIMARY data source for that Merchant Center account, which replaces whatever feed supplies your Shopping ads today, and the card says so before you approve. Only products that changed since the last publish are sent. Nothing is published if the build has an error Google would reject.
What we never touch: Bids, budgets or campaigns. Your Merchant Center account settings. Shipping, tax or returns configuration. Deleting a data source. Anything in an account you did not connect.
Guardrails, enforced in code
- Publishing is off by default on the connection, and arming it takes a confirmation
- A first publish also requires typing the word PUBLISH, because it replaces the feed serving your ads
- The feed is rebuilt and revalidated at the moment you approve, so a card drafted against an older catalog cannot publish a feed nobody reviewed
- A build with any error Google would reject cannot be published at all
- Merchant Center accepts items one at a time, so a publish reports each item's outcome and can end partial rather than claiming success
Where this stands today. The connector, reads, catalog import, feed audit, rules and preview are implemented and open to the controlled beta. Publishing stays off until the write switch is armed and the exact publish is approved, and remains under supervised validation until publish, verify and recovery have a complete production evidence pack. If Google refuses to list your accounts at connect time, the screen says so and names it as ours to fix. Implemented code is not a customer-available publishing promise.
TikTok Ads
Why it is here. The hole in a blended number, for a store whose third channel we cannot see.
Permissions we request: There is no permission string in our code to print here. TikTok fixes an app's permission set when it approves the app in its own developer portal, so our authorize request sends no scope parameter at all. That makes this the one row on the page where the honest answer is a name from somebody else's dashboard rather than a literal from ours.
The set was read-only until 2026-08-18, when TikTok approved a second application covering campaign, ad group and ad management, audiences, creative, catalogs, pixels and measurement. We deliberately left out TikTok Shop and GMV Max, which are a campaign type this product does not use, and Automated Rules, because nothing here ever writes without your approval and holding a permission for unattended changes would contradict that. TikTok's own consent screen shows you the set you are actually granting before you approve it, and that screen is the authority, the same way Meta's is. TikTok reports the granted set back to us as numeric ids and we store what it reports rather than what we asked for. It publishes no map from those numbers to permission names, which is why the check in front of every TikTok write still does not recognise the grant and still refuses.
What we read
- Which advertiser accounts your login can reach: advertiser id and name
- Account details: name, currency, timezone and account status. That is a second call, because the account list carries none of them
- Daily performance for the account: spend, impressions, clicks, conversions and TikTok's own attributed purchase value
- The same figures per campaign, with the campaign id and campaign name, day by day
A day TikTok sends no row for is stored as unread rather than as a zero. TikTok filters days with no data out of the response entirely, so a day with no spend and a day we never read arrive looking identical, and writing zeros there would understate spend and inflate every ratio built on it. A window TikTok answers as partially successful is stored incomplete rather than whole. The purchase value above is what TikTok attributed to its own ads: there is no attribution-window parameter on the reporting endpoint, each ad group carries its own windows, so those figures are not comparable with Meta's and are never labelled revenue.
What can change, after you approve it
- Create a new campaign, ad group and ad in one card, every object paused. Off for every account today, and held off by three separate things: the capability switch is a constant in our source, the write switch does not accept TikTok as a provider at all, and the permission check in front of every TikTok write does not recognise the grant TikTok reports back. When on, nothing is activated by the approval: the tree is created paused and you turn it on yourself in TikTok Ads Manager. TikTok publishes no way to validate a campaign before creating it, so the card says we checked it and TikTok did not.
What we never touch: Deleting anything. Changing a campaign, ad group or ad that already exists: budgets, bids, targeting, schedules and statuses. Uploading creative: the video has to be in your account already and we send its id. Audiences, pixels and the Events API.
Where this stands today. TikTok approved the developer app and the read code is implemented, but no sanitized production read evidence pack is complete. New grants are restricted to allowlisted supervised tests. Campaign creation is switched off, numeric write-scope mapping still fails closed, and no TikTok write is offered. No audit check reads TikTok yet; the eleven Meta checks and Google’s twenty-one-rule catalog are separate engines.
Shopify
Why it is here. Your revenue and returns are what turn a ROAS number into a profit judgement.
Permissions we request:
read_ordersread_productsread_reportsread_analyticsread_inventoryAll five are read permissions. read_inventory reads a variant's unit cost, so a product's margin can inform its Shopping feed; the other four cover sales and catalog. We deliberately do not request read_all_orders, the protected permission that would let us list orders older than 60 days, because the reporting gain does not justify the access. Shopify shows you the permission list on its own install screen before you approve it, and a store that granted a wider set at some earlier install keeps that grant: what bounds the reads is the code, and no Shopify customer, line item or fulfilment endpoint is called anywhere in it.
What we read
- Shop settings: name, domain, currency, plan and timezone
- Daily sales from Shopify's own analytics: gross sales, discounts, returns, net sales, total sales and order count
- Product count
- Order count for a window, and a revenue total summed from the orders themselves
- Cancelled order count for a window
The revenue total for a window is a sample and the sample size travels with the figure. Orders are read 100 rows at a time and we follow Shopify's cursor rather than stopping at the first page, up to a budget of 50 pages. Past that the window comes back marked incomplete instead of being passed off as the whole total. When Shopify counts orders and returns none of them, revenue comes back empty with the reason in plain language, never as zero. A day holding an order whose money we cannot read is removed whole and named, from the live total and the stored series alike, so the two never disagree about what a day was worth.
What can change: Shopify is read-only today. It is absent from the list of providers the write switch accepts, so the switch refuses to arm for it, no proposal tool exists, and the code that executes approved changes has no Shopify branch. The only request we send to Shopify that is not a read is the install handshake itself.
What we never touch: Customer names, emails and addresses. Line items. Fulfilment and shipping. Discount codes. No customer, line-item or fulfilment endpoint is called anywhere in our code.
Where this stands today. Your gross margin sets the ROAS a campaign has to clear. Once there are enough measurable returns, that bar is raised by your own return rate rather than by an industry figure. Blended MER joins live Meta spend to Shopify revenue in one number, and it excludes Google Ads spend, which the number says on its face. New installs are closed while Shopify's own app review completes; a store already installed keeps syncing every night.
Google Analytics 4
Why it is here. What the site itself recorded, checked against what an ad platform claims for the same traffic.
Permissions we request:
https://www.googleapis.com/auth/analytics.readonlyRead-only by definition. This permission cannot change anything in your property, and Google shows it to you on its own consent screen before you approve.
What we read
- Your GA4 account summaries and the property list under them, so you can pick a property
- Sessions, total users, engaged sessions, key events, ecommerce purchases, purchase revenue and total revenue, by traffic source and medium, day by day
- The same window rolled up by channel group: paid social, paid search, organic search, direct, email and referral
These are the site's own numbers, not an ad platform's attributed figures, and they will not match what Meta or Google Ads reports for the same traffic. That difference is the reason to read both, not an error in either one. A property GA4 reports no currency for comes back with its revenue named as an unknown unit rather than assumed to be dollars.
What can change: Nothing. There is no write permission and no write path.
What we never touch: Audiences, custom dimensions, user-level or demographic breakdowns, and real-time reports. The seven metrics listed above are the whole set we request, and no audience, demographic or real-time endpoint is called anywhere in our code.
Where this stands today. The connector, nightly sync and two live read tools are implemented, Google approved analytics.readonly, and GA4 is open to the controlled beta. Production evidence is pending: no sanitized connect-and-read pack is complete yet. No audit check reads GA4 and no write path exists.
Google Search Console
Why it is here. What people searched to find your site, and the pages they landed on, read nightly and live in chat.
Permissions we request:
https://www.googleapis.com/auth/webmasters.readonlyThis is the read-only variant. It cannot add a site or submit a sitemap even if we wanted it to. Google classes it as non-sensitive, so it needed no verification.
What we read
- The list of your verified sites, so you can pick one
- Search queries and the pages they landed on, with clicks and impressions, day by day
What can change: Nothing. There is no write permission and no write path.
What we never touch: Sitemaps, URL inspection, indexing coverage, mobile usability, Core Web Vitals and rich-result status. Only search queries and pages are read.
Where this stands today. The connector, the two spine tables, the nightly sync and two live agent read tools are built and shipped, and Search Console is open to the controlled beta: a connected site is read every night the same way Meta and Google Ads are, and the agent reads its search queries and pages live in chat. The button stayed closed for a week on the belief that webmasters.readonly needed Google's verification; it is a non-sensitive scope and never did. Production evidence is pending: no sanitized connect-and-read pack is complete yet.
Section 04 · what we have not built
What we have not built, named before you find it.
There is no connector, no login flow, no API client and no agent tool for any of these. Not a beta, and not behind a flag. We write not built rather than planned, because planned is a delivery promise and there is no date behind one.
If your money is mostly in one of these, Sable Mako has little to offer you this month. Tell us which one at support@sablemako.com and it moves up the list.
Two more things worth knowing before you connect
- Google service businesses have their own audit path. A service workspace runs twelve applicable Google checks for selected lead outcomes, campaign goals, settled spend and privacy-safe call patterns. Ecommerce runs twelve. Qualified-lead deterioration remains unassessed until a tenant-bound CRM series supplies compatible cohorts. Meta messaging campaigns are still excluded from purchase-based profit checks.
- Team access is deliberately simple. Solo includes one login; Studio, Agency and Scale allow multiple people. A workspace has Owner and Member roles. Members can use the agent, read audits and approve changes for the brands the Owner has given them, while billing, account connections and write access stay with the Owner. There is no read-only role or ownership transfer yet.
Section 05 · why we ask for this much
Why we ask for this much and no more.
The audit is why we ask to read.
Google’s catalog contains twenty-one deterministic rules, with twelve selected for ecommerce and twelve for service businesses. Every finding names the rule, entity and number behind it. One initial audit is included per eligible account. Repeat audits, daily monitoring and alerts require an active trial or plan. Meta's eleven checks are implemented but Meta remains reviewer-only during app review.
The daily watch is why we ask for history.
With an active trial or plan, once a day from 07:00 in your brand's own timezone, each eligible connected ad account is read again and compared with its last scheduled run. You are alerted on new or worse findings only, never on the same problem twice.
The write permission is the one we cannot narrow.
Meta requires ads_management for the three Meta changes, and Google publishes a single Ads permission that covers reads and writes together. Neither platform offers a read-only alternative, so read-only is a behaviour we enforce rather than a permission we request. That is what the two switches above are for.
Section 06 · connecting and disconnecting
Connecting goes through their front door. Leaving takes one click.
- You connect through each platform's own login flow. The permission screen you approve comes from Meta, Google or Shopify, and we never see or store a platform password.
- Access tokens are encrypted with AES-256-GCM before they reach the database, under a key held in the server environment rather than in the database, and each token is cryptographically bound to the one connection it belongs to.
- Writes start off. You arm them on one connection at a time and confirm the dialog. Turning them back off takes one click and no confirmation.
- Meta's long-lived login tokens run about 60 days and we do not renew them for you. There is no Meta refresh path in our code and no stored expiry, so the first sign is a read that fails and the fix is to reconnect Meta from Integrations. Google connections hold a refresh token and renew themselves.
- Disconnecting deletes the stored credential outright. It is a delete rather than a flag. Metrics already pulled stay, so your history does not develop a hole where the connection used to be.
- You can revoke access from Meta, Google or Shopify at any time without touching Sable Mako, and that ends our access on the spot. If you delete your account, revoke there as well: we do not do it on your behalf.
Data handling, subprocessors and deletion are set out in the privacy policy, and the controls behind all of this are on the security page.
Section 07 · before you connect
Before you connect. The questions people actually ask.
Can Mako change my campaigns without asking?
No. Write access is off on every new connection, the change tools are not even sent to the model while it is off, and each individual change needs its own approval. After a change runs, Mako re-reads the platform and reports success only when the platform agrees.
What if I connect and never turn writes on?
Read-only use does not require turning writes on. During an active trial or plan, repeat audits, the daily watch, alerts, chat and analysis can run while every platform change remains disabled. Your included first audit also runs before writes are enabled.
What exactly can it change, at most?
Forty operations across four platforms: pause or activate a Meta campaign, set a Meta campaign daily budget, and move budget between two Meta campaigns or two ad sets. On Google Ads: pause 2–10 exact enabled campaigns in one atomic batch; end one exact running experiment without promoting treatment changes; read and permanently dismiss one exact Google-native recommendation without applying it; pause or enable a Google campaign; permanently remove one exact already-paused campaign; create or change one Google Ads label relationship; attach, pause, enable or remove one existing Google Ads campaign or ad-group asset relationship; create one advertiser-authored account-level callout; create one detached call asset for a named Search campaign; create one detached Google-hosted lead form; change one existing Performance Max asset group’s name, status, HTTPS destinations or display paths; add or remove one Performance Max search-theme or existing-audience signal; include or exclude one existing non-root Performance Max or Standard Shopping product-group leaf or change one eligible Manual CPC product-group bid; rename one existing Google campaign; change Search Partners; change exact campaign dates or tracking settings; change exact country, region, radius or language targets, demographic exclusions, device modifiers, complete schedules or placement exclusions; set or clear one exact target CPA or target ROAS on an existing eligible standard strategy; set or clear one exact target CPA or target ROAS on an existing eligible portfolio strategy; include or exclude one exact campaign conversion goal or restore account defaults; create one exact secondary website or call conversion action and return Google’s code for installation; replace the complete reviewed text and HTTPS destinations of one paused responsive search ad; set a Google campaign daily budget; change one existing shared daily budget’s amount or name or one eligible campaign total budget; add negative keywords to a Google campaign; remove campaign negatives; add, pause, enable or remove positive keywords in one ad group; pause, enable or rename one Google ad group; pause or enable one exact existing Google ad; permanently remove one already-paused Google ad; change a keyword CPC bid, HTTPS destinations or match type; change Search location-presence mode; create or remove a paused Search ad group, change its Manual CPC bid or manage one existing audience link and mode; and create a Google campaign paused. The final two operations publish the product feed to Merchant Center and create a TikTok campaign paused. Google Ads campaign creation is released in Production for admitted workspaces and creates every object paused. TikTok Ads campaign creation remains switched off for every account. All thirty-two Google action families are independently gated and admitted per workspace; the Google write switch cannot expose an unreleased family. Feed publishing stays off on each connection until its own controls are enabled, and every available action still requires exact approval. Broader bulk changes, experiment creation, experiment scheduling, promotion and graduation, Google’s generic recommendation apply endpoint, arbitrary product-tree construction, asset creation other than account-level callouts, detached call assets and detached Google-hosted lead forms, asset editing, audience creation and conversion-action editing remain outside this write surface. That is the complete list, and a test in this codebase fails the build if another operation appears without this page being rewritten.
A change failed halfway. Now what?
A budget move is two steps, and if the second fails the first is put back automatically and the result is shown to you. For a single change that executed but did not verify, the card says so and names the discrepancy. A verified reversible receipt can prepare the opposite change, but that undo is a new proposal with fresh checks and its own approval; it never runs automatically.
Do you read my customers' data from Shopify?
No. We read shop settings, daily sales totals, product count, order counts and order totals. No names, emails, addresses, line items or fulfilment, and no endpoint that would return them is called anywhere in our code.
Do you need my Meta or Google password?
No. Connections run through each platform's official login flow and we store a revocable token, never a credential you typed.
My platform is not here.
Then it is not supported, and there is no beta and no flag that changes that. Nothing on this page is a roadmap. Email us and we will tell you honestly whether it is close.
What does connecting cost?
Connecting Google Ads and running one initial deterministic audit needs no card. Repeat audits, daily monitoring, alerts and the agent require an active trial or plan. Meta and TikTok Ads are not ordinary beta connection options yet.
Controlled beta
See what your Google Ads account is doing.
Apply for a supervised design-partner place. One initial deterministic audit is included before you choose a plan.
No card for the included audit. Nothing changes without exact approval.
Receipts
- The permission strings on this page are the literal values our code sends. The platform's own consent screen is what actually grants them, and it shows you the set before you approve.
- Write access is stored per connection and starts off. While it is off, the change tools are left out of the request sent to the model, so the agent is never handed them.
- A proposal older than 24 hours is refused and has to be asked for again, because the numbers on the card describe a moment that has passed.
- Every approved change is executed once and then verified by re-reading the platform in the same request. Success is defined by the platform's own value, never by the platform's response.
- Shopify revenue for a window is summed from the orders themselves and carries its sample size. Orders are paged through 100 rows at a time up to a budget of 50 pages, and a window that runs past it is returned as incomplete rather than as a total.
- Platforms marked not built have no connector, no login flow, no API client and no agent tool anywhere in the product.
- Tokens are encrypted with AES-256-GCM under a key held outside the database, and the row holding one is deleted when you disconnect.
- Meta login tokens last about 60 days and we do not renew them. Nothing in our code stores their expiry, so the first sign is a read that fails.