Skip to main content

Overview

Some storefronts run through direct ad platform adapters instead of a publisher sales agent. Before Scope3 can discover products, create media buys, sync creatives, or read delivery from those adapters, the customer must connect the relevant advertiser account to Scope3 through the platform’s own account-sharing or OAuth flow. This guide is written for legal, procurement, and platform admins who need to approve the access request. For what a connection actually is — organization vs advertiser accounts, manager-account (MCC / Business Manager) expansion, account types, and how discovered accounts map to your advertisers — see Ad Platform Accounts. When Claude, ChatGPT, or another generic MCP client operates a connected account, it can call get_adcp_tool_schema before a write. Start with the tool name, then inspect the returned nested paths—for example, packages[].targeting_overlay before create_media_buy, and revision plus packages[] before update_media_buy. This returns the exact versioned schema fragment on demand without loading every platform contract into the initial tool list. Clients should inspect those fields rather than guess targeting, creative, budget, or lifecycle request shapes.
This page covers ad platform account access such as Meta, TikTok, Google Ads, Snap, LinkedIn, Pinterest, Reddit, and Amazon Ads. Google Ads is separate from Google Ad Manager. For Google Ad Manager inventory-source setup, see the Storefront onboarding guide.

What Write Access Means

When Scope3 asks for platform write access, it is asking for permission to operate campaigns and related advertising objects for the advertiser accounts that the customer explicitly grants. It does not mean Scope3 needs broad business administration rights. Write access may be used to:
  • Create, update, pause, or resume campaign objects, ad groups or ad sets, ads, budgets, targeting, and flight dates.
  • Upload or sync creative assets and create platform-native creative records.
  • Create or update first-party audience segments when the customer enables audience sync.
  • Create or update product catalogs or feeds when the media-buy workflow uses catalog products.
  • Read delivery, spend, approval status, pacing, and performance reporting.
  • Send conversion or event data when measurement is configured for the advertiser.
  • List connected advertiser accounts so the customer can choose the right one.
Scope3 does not need permission to:
  • Add, edit, or delete users.
  • Take ownership of the customer’s business account or advertiser account.
  • Manage unrelated advertiser accounts that were not shared with Scope3.
  • Change security settings, login settings, business verification, or platform account ownership.
  • Manage billing users or finance roles unless a customer has a separate, explicitly approved billing workflow.

Buyer-Selected Optimization Goals

Connected-platform products advertise the exact optimization_goals they can apply. Interchange rejects malformed or product-incompatible metrics, events, durations, and targets before creating provider objects. Provider-owned event source identities are preflighted when the platform exposes authoritative inventory; otherwise the provider validates them during creation, and a rejected or mismatched response fails the create and triggers cleanup. Interchange also verifies the provider’s returned optimization field before creation can complete. Per-auction bid ceilings are pricing controls, not optimization goals. They are not inferred from cost_per or other optimization targets. Provider-confirmed goals are not yet echoed on package status because the current AdCP package response schema has no optimization_goals field. Use the platform’s partner or manager-account sharing flow where available. The customer remains the owner of the business and advertiser accounts, and can remove or reduce Scope3’s access from the platform console at any time. For activation workflows, choose the least broad role that can both manage ads and read reporting. Use read-only access only for reporting-only pilots. When an agency runs media for several clients, the pattern is the same on every platform:
  1. Each client grants access on the platform side — to the agency’s container (Business Manager, manager account / MCC, Business Center) or, on platforms without an organization container, to the agency’s user.
  2. The agency connects its own login in Interchange, once.
  3. Every client account the grant reaches is discovered under that one connection, grouped under the manager account where the platform has one.
  4. The agency maps each client account to the matching advertiser on the Advertiser mapping tab (Settings → Connections).
Organization-level linking is the agency-correct move because one grant surfaces the whole client portfolio. Linking a single client-shared ad account also works, but each additional client then needs its own connect. The per-platform sections below include an Agency setup subsection with the client-side steps.

Platform Summary

Targeting Support Differs by Platform

Every platform accepts a different subset of targeting_overlay. Ask the platform rather than assuming: get_adcp_capabilities returns media_buy.execution.targeting, which lists exactly the dimensions that platform applies. On create_media_buy that declaration is enforced, not advisory:
  • A dimension the platform declares is applied. If it appears in media_buy.execution.targeting, the campaign delivers against it.
  • A dimension the platform does not declare is refused. The request fails with HTTP 400 and error code UNSUPPORTED_TARGETING_DIMENSION, naming the dimension and the package it came from. Nothing is created — the rejection happens before the platform is called at all, so there is no half-built campaign to clean up.
A targeting request is never accepted and then ignored. If a call succeeds, every dimension you sent is in effect; if a dimension cannot be honored, you get an error instead of a campaign that quietly delivers to the wrong audience. When you need a dimension a platform refuses, either drop it or use a platform whose capabilities include it.

Age targeting from a brief

Age is currently product targeting, not a targeting_overlay dimension. Scope3 uses only numeric bounds written explicitly in the brief and applies an 18+ policy floor. It does not ask the model to invent bounds or approximate an unsupported request. For example, ages 21-35 is exact on Meta and Spotify, but is not exactly representable by the current Snap, TikTok, or Pinterest buckets. Open-ended, disjoint, ambiguous, negated or exclusionary, or below-18 ranges return no actionable product. A seller or upstream sales agent can make an age-baked product eligible by returning Scope3’s exact product targeting declaration; Scope3 composes only products whose declared bounds match the brief and never guesses the seller’s mapping. Composed products carry that declaration forward. Refining several products preserves age only when every selected product declares the same exact target; conflicting or undeclared targets are not combined. Unknown-age delivery is excluded by default for any constrained-age request. Meta also accepts an explicit request to include or exclude people whose age is unknown; other adapters reject an include-unknown request. For supported wording, provider boundaries, and response fields, see Exact age targeting.

Changing targeting on an existing buy

update_media_buy is narrower than create_media_buy, and the difference is per-platform: Two platform shapes are worth knowing before you build a package:
  • Meta, Google Ads, Snap, TikTok, LinkedIn, and Spotify accept top-level provider-supported ISO 3166-2 regions. Their current region searches do not return enough ISO hierarchy to prove a deeper subdivision, so Scope3 refuses nested codes rather than risk substituting a larger same-named parent. Meta’s location taxonomy also does not expose French départements as region targets. Pinterest verifies exact ISO codes; Reddit and Universal Ads pass declared ISO-style codes directly. Those paths do not need this name-based restriction.
  • A Spotify ad set carries a single country, so a Spotify package declaring more than one country is refused rather than delivering to just one of them. Split those countries across packages.
  • Google Ads targets geography at the campaign level rather than per ad group, so every package in one Google media buy must declare the same geography. A buy whose packages disagree is refused with INVALID_PACKAGE_MIX before anything is created. Use separate media buys for separate geographies.

Reading geography back in delivery reports

get_media_buy_delivery breaks delivery down by geography when you ask for it through reporting_dimensions.geo, and what you get back depends on the platform: On Google Ads this means region targeting applies to delivery but is not yet visible in reporting — you can target a region and cannot yet read that region back. If you need to reconcile spend against a region on Google, split the geographies across separate media buys, which reports them separately. Where geography can be changed, it is declared state, not an edit: the regions you list are the regions that deliver, and a region you stop listing stops delivering. Sending geo_regions: [], or omitting geo_regions while supplying geo_countries, returns delivery to country level. Omitting targeting_overlay entirely leaves targeting untouched, so you can change budget or dates without restating geography.
get_adcp_capabilities describes what a platform applies on create_media_buy; it does not yet distinguish the create and update paths. Until it does, treat the table above as the update contract.
Meta applies audience_exclude to Custom and Lookalike Audiences. Other exclusion dimensions remain platform-dependent and may be refused. Check get_adcp_capabilities for the current list.

Meta

Custom and Lookalike Audience targeting

Use the AdCP-native targeting_overlay.audience_include and targeting_overlay.audience_exclude arrays on Meta packages. Each value is the signal_id returned by get_signals for Meta. Inclusion maps to Meta Custom Audiences; exclusion maps to excluded Custom Audiences. The same fields are returned by get_media_buys for both managed buys and read-only tracked buys. Before create or update, Interchange reads the selected ad account’s complete audience inventory. Every requested ID must belong to that account and Meta must mark it usable for delivery. Missing, deleted, owned by a different account, or non-deliverable IDs are refused before Interchange sends a write to Meta. After a write, both audience sets must match Meta’s readback exactly. If the readback after creation differs, Interchange removes the new campaign. If an update differs, Interchange restores the previous targeting and verifies the restoration with Meta. On update, each supplied audience field is declarative: it replaces the full include or exclude list. An empty array clears the list; an omitted field is preserved. The old Meta-specific targeting_overlay.signals extension is no longer accepted; migrate it to audience_include. Scope3’s validated Meta onboarding path uses an Ad Account owned by a Meta Business Portfolio. Personal ad accounts can appear during account discovery, but campaign activation with them has not been validated. For production onboarding, use a Business Portfolio-owned account. In Meta Business Suite or Meta Business Manager, add the Scope3 Business Portfolio (Business ID: 1091793362240769) as a partner, then grant it access only to the advertiser assets required for the workflow. Default grant for activation:
  • The relevant ad account.
  • Campaign management access.
  • Performance reporting access.
Additional assets may be needed depending on the campaign:
  • Facebook Page or Instagram account access when ads use those identities.
  • Facebook Page advertising and lead access when Instant Forms are used.
  • Pixel or dataset access when conversion events or conversion optimization are configured.
  • Catalog access when catalog products are used.
Meta’s OAuth consent can include ads_management, ads_read, and business_management. Page-backed ads also request pages_show_list, pages_read_engagement, and pages_manage_ads; Instant Form discovery also requests leads_retrieval. Reconnect an existing Meta connection after these Page or lead permissions are added so Meta can issue a token with the new grants. The customer-side asset grant should still stay scoped to the specific business assets needed for the advertiser workflow. For Instant Form discovery, Interchange uses Meta’s delegated Page access only for that Page’s form read; the Page token is not returned in adapter results or stored as account data. Scope3 does not need full control of the customer’s business portfolio, broad account-settings control, billing administration, or permission to add, edit, or delete users.

Real-time Meta signals

After you select a Meta ad account, Scope3 automatically installs and repairs its Meta app subscription for processing completion, objects with issues, ad recommendations, creative fatigue, and product-set issues. No separate Ads Manager setup is required for each connected account. The connection must keep campaign-management permission so Meta allows the subscription and subsequent authoritative readback. These notifications reduce detection latency; they do not replace provider readback. Scope3 verifies each signed notification and, when it identifies an ad, ad set, or campaign, reads that object with the current connection before changing canonical campaign or creative state. Polling remains the fallback if delivery is delayed or missed, and duplicate deliveries are deduplicated. get_media_buys and list_creatives can include recent observations in the response-level ext.scope3_provider_signals object as { version: "1", provider: "meta", signals: [...] }. Creative-fatigue entries include the stable creative_id when available, the fatigue level when Meta provides it, and the observation time. Meta emits creative-fatigue notifications for active ads only. These observations are Scope3 extensions, not canonical AdCP status fields.

Brief planning in MCP hosts

When Claude, ChatGPT, or another MCP host calls Meta get_products with a non-empty brief, Scope3 uses assisted planning by default. The response includes the interpreted objective, optimization, geography, demographics, creative format, assumptions, and rationale. If the brief is ambiguous or asks for a targeting or creative decision that Scope3 cannot represent exactly, the call returns clarification requirements and no actionable product instead of silently guessing. Meta brief planning accepts exact inclusive age bounds from 18 through 64. For example, ages 21-35 creates product targeting with age_min: 21 and age_max: 35; familiar ranges such as 25-34 continue to work unchanged. The numbers must appear explicitly in the brief. Scope3 does not use model-inferred age bounds, and asks for clarification when ranges are below 18, disjoint, or ambiguous. To control delivery when Meta does not know a person’s age, explicitly say whether to include or exclude people on WhatsApp whose age is unknown. If an explicit constrained-age brief does not make that choice, Scope3 excludes unknown-age delivery; it never silently enables it. These demographics travel with the selected product; the AdCP targeting overlay does not yet expose demographic fields. Use buying_mode: "wholesale" only when the buyer explicitly wants raw Meta catalogue discovery without brief-strategy provenance. Wholesale discovery does not claim that Scope3 interpreted the advertiser’s brief. Connected-account campaign planning uses its separate propose-and-accept flow before an assisted write.

Meta performance goals and bidding

Meta products declare the performance goals they can execute and accept one primary goal per package (max_optimization_goals: 1). Send that choice in the standard AdCP optimization_goals array. Scope3 validates the goal against the product’s Meta objective before creating or updating anything, then reads back the exact Meta optimization goal, billing event, and bid settings. Media-buy reads return the effective standard goal rather than the product’s default. When buyers send ranked alternatives, Meta considers explicit priorities first and executes the lowest-numbered priority. Ties preserve array order, and goals without a priority follow every explicitly ranked goal. This deterministic selection matches the upcoming AdCP 3.2 contract while Meta continues to accept only one primary goal. In the upcoming AdCP 3.2 contract, bidding is separate from the goal. Scope3’s Meta adapter contains a bounded provider-mapping and readback layer for automatic bidding, max_bid as a hard per-auction ceiling, cost_per with strength: "cap", and roas with strength: "floor". The released AdCP 3.1 handlers do not wire or expose that canonical input: requests using bidding fail with a version-gap error instead of being accepted through an untyped field. A released and negotiated 3.2 SDK must also supply the final typed handler, pricing-option, inheritance, and value-currency validation before the canonical surface is enabled. Manual bid_amount, target-strength cost/ROAS policies, and policy combinations remain unsupported because Meta cannot preserve those semantics exactly. The deprecated bid_price field remains accepted and follows AdCP’s deterministic migration rule. Meta advertises legacy max_bid: true, so bid_price normalizes to canonical bidding.max_bid; it is not a second bidding mode. Legacy monetary goal targets normalize conservatively to target strength and therefore fail closed on Meta rather than being strengthened into a cap or floor. Canonical bidding is exposed publicly once the released AdCP SDK carries the 3.2 schema; no private ext field is used in the meantime. Unsupported objective/goal pairs, targets, reach units, and view-duration thresholds also fail before a Meta write. Check each product’s metric_optimization, vendor_metric_optimization, and conversion_tracking fields for its exact accepted set. Vendor-metric goals also require the matching vendor entry in the package’s standard committed_metrics array so optimization and delivery reporting use the same measurement key. Add that append-only contract when creating the package. AdCP update packages do not currently carry committed_metrics, so Scope3 rejects an update that would introduce a different vendor goal instead of inventing a private field; existing commitments continue to be reconciled after later goal changes. AdCP target_frequency is a soft reach-optimization band, while Meta’s available frequency control is a hard delivery cap; Scope3 rejects the soft goal instead of silently changing its meaning. Use targeting_overlay.frequency_cap only when a hard cap is intended.

Pixel and dataset ownership

Meta measurement setup is scoped to the selected ad account. Scope3 lists the complete Pixel/Dataset inventory Meta authorizes on that account; if Meta returns no sources, Scope3 reports an empty list instead of substituting the ad account ID. Installation snippets and Event Match Quality appear only for a source verified in that inventory. A requested missing or foreign source is reported as failed. When you request specific source IDs, Scope3 returns only those IDs and does not inspect Event Match Quality for other owned sources. Before sending a conversion event, an account-bound connector rechecks that the Pixel/Dataset is still authorized. If Meta discovery, pagination, or ownership verification fails, Scope3 sends no conversion event. The connector rejects a request account that differs from its authenticated selected account, and a pagination continuation cannot change API version, account, or resource. MCP hosts do not need to add an account field to log_event: a complete sync_event_sources call learns private tenant-scoped ownership for the selected account. A later host-neutral event resolves exactly one fresh learned binding, then rechecks the complete Pixel/Dataset inventory with the current connection before sending. Missing, ambiguous, stale, revoked, or temporarily unavailable ownership sends nothing and returns a re-sync or retry error instead of guessing an account.

Built-in platform conversions

Some ad platforms observe outcomes on their own surfaces, so no buyer Pixel, SDK, or server event is required. These sources use stable <platform>:<capability> IDs and appear in sync_event_sources only when the selected account returns affirmative eligibility. They are platform-managed and discovery-only. Attempts to upsert or delete a built-in source fail for that source without changing it; log_event also rejects built-in sources. Scope3 does not synthesize health status or scores for built-in sources. Meta can return meta:onsite for shop purchases, meta:messaging for Messenger contacts, and meta:instant_forms for active Instant Form leads. An Instant Form is eligible only when the same Meta connection is authorized for the selected ad account, Meta grants that connection an advertising task on the owning Page, the Page returns the active Form, and the Page is published. It does not have to appear in the account’s separate promotable-Page list. That exception applies only to Instant Forms—shop and messaging sources still require an eligible promotable Page. The source lists only its native event type. An event optimization goal referencing one of these IDs is accepted only for a compatible Meta product and eligible Page; Scope3 creates the campaign paused and verifies Meta’s exact optimization goal, destination, and Page-backed promoted_object before returning success. Amazon advertising profiles return amazon:onsite for Amazon-observed product views, add-to-cart events, and purchases. Google Ads accounts return google:youtube for YouTube-hosted actions and google:onsite for Google-hosted actions; each source’s event types come from those actions. Other connected platforms do not silently claim support: TikTok, Snap, Pinterest, Reddit, LinkedIn, and Spotify do not currently expose built-in event sources through Scope3; their existing buyer-instrumented sources are unchanged.

Meta creative format discovery

Meta creative-format discovery honors exact legacy named-format references, required asset types, minimum width and height, and case-insensitive name search. These filters compose: every supplied filter must match. A request that matches nothing returns an empty list instead of the complete Meta catalog. Paginated discovery returns a bounded page and a signed continuation cursor. The cursor is short-lived, retry-safe, and bound to the authenticated tenant, account context, filters, page size, and current catalog revision. Safe retries return the same page; changed, expired, or tampered cursors are rejected. Filters that the static Meta catalog cannot verify—such as publisher/property, accessibility, disclosure, input/output transformation, responsive, and maximum-dimension filters—return an error instead of being ignored. Meta creative sync is scoped to the selected ad account. Image and video creatives keep the caller’s creative ID and declared Meta format across sync, list, and media-buy operations, while the provider’s creative ID remains the trafficking identity. Submitted image/video assets are returned on list. Review status comes from explicit provider review evidence on ads; paused, active, or archived lifecycle status alone is never reported as approval. A creative that has not been attached to an ad remains processing. Meta also discovers eligible existing posts automatically. A Facebook Page is the publisher identity; each boostable post from a Page authorized for the selected ad account appears as a separate read-only creative with a typed published_post asset. Buyers do not copy Page or post IDs into Scope3 to make this inventory appear. Discovery uses the Meta connection’s pages_show_list and pages_read_engagement permissions, so connections made before those permissions were requested may need to be reconnected. Page-post discovery is bounded across the whole account and fails without returning a partial post inventory if Meta cannot complete it safely. Existing-post discovery is currently read-only for ordinary buyers. Products do not yet advertise the existing-post format, and published-post sync or media buy creation remains restricted to Scope3’s signed, paused, no-spend provider conformance run. Image and video creative workflows are unchanged. For file-based Meta image and video formats, the uploaded media and link_url are required. primary_text, headline, and image description are optional; when supplied they populate Meta’s message, title/name, and description fields. The CTA defaults to LEARN_MORE when call_to_action is absent. The Page comes from an explicit authorized page_id, or the sole Page authorized for the ad account; zero or multiple eligible Pages fail before any provider write. Missing media, destination URL, or resolvable Page also fails closed, so Scope3 never syncs a hollow Meta creative. TikTok creative sync keeps your original creative ID and TikTok format across adapter restarts. Scope3 stores uploaded media and Spark published-post references under the selected advertiser, then uses the provider media or post ID as the typed TikTok trafficking reference. Mapped list rows return the normalized submitted image or video URL. Retrying the same upload reuses provider media after readback; an upload whose outcome is unknown is not repeated automatically. Image success always requires an exact, displayable readback from the selected advertiser’s media library. For video, Scope3 records the TikTok video ID before checking processing status, so a temporary missing-status response resumes against the same video instead of uploading another copy. The same exact-ID recovery applies if the adapter restarts between its final durable journal steps. Structured TikTok format references must use the format authority returned by list_creative_formats. Image and video URLs must include a recognized file extension that matches both the supplied asset type and selected TikTok format; extensionless, audio, and mismatched media are rejected before upload. Changed images use a bounded source-digest filename to satisfy TikTok’s per-account filename uniqueness requirement. Product-selected TikTok uploads use the URL-free format_kind and format_option_ref returned by the product. Uploaded image, video, and carousel formats require authored display_name and ad_text (12-100 characters); Scope3 stores that copy with the durable media identity and uses it when the ad is created. Missing native copy fails before trafficking—Scope3 does not insert placeholder brand names or sponsored-content text. Post-buy TikTok package attachment is currently rejected before media upload; registering media without creating and reading back an ad is never reported as package coverage. TikTok carousel is available for Reach, Traffic, Website Conversions, and App Promotion products. Supply one tiktok_carousel creative with 2-35 distinct square image assets in the advertised order. Interchange uploads every image to the selected advertiser and waits for TikTok to mark each exact image both displayable and carousel-usable. It then creates one paused CAROUSEL ad and requires TikTok to return the same complete ordered image list. Missing, duplicate, reordered, substituted, or ineligible images stop the campaign before activation. list_creatives returns the original carousel as one source creative instead of exposing its uploaded children as separate duplicates. Other hosted social adapters also preserve product-scoped canonical format selections. Google validates the complete required role/count matrix before building a paused ad or Performance Max asset group, then reads the exact provider assignment back. Its products expose uploaded Responsive Search, Responsive Display, video, Performance Max, and Demand Gen formats; generated display and generated-offering refs fail before provider I/O until a generation writer exists. Pinterest products expose single-image, video, and max-width video Pins. Generated, carousel, collection, showcase, and Idea Pin refs fail before upload rather than being flattened into a single Pin. Pinterest requires authored Pin title and account/package context before upload and confirms the paused ad. Spotify products expose authored audio, podcast audio, video, and in-feed display formats. Generated Spotify refs fail before asset creation until a generation writer exists. Spotify requires authored advertiser/brand name, tagline/headline, and a call_to_action text asset selected from the format’s advertised CTA values, plus the declared click_url destination. It applies the same validation in sandbox; live assignment is acknowledged only after paused-ad readback. Amazon recognizes its canonical catalog selections but returns a visible unsupported result until its creative writer can create and read back the provider ad; asset upload or an ASIN alone never counts as creation. Reddit’s current self-serve writer supports canonical freeform promoted posts only, and LinkedIn supports canonical inline creatives during media-buy creation but returns a visible unsupported error for post-buy creative sync. Unsupported format/writer combinations never count as package coverage. Reddit freeform and LinkedIn inline creatives also require exact paused provider-ad/creative readback before assignment is returned. TikTok’s Marketing API does not expose a provider-native creative translation/localization operation. Interchange therefore does not advertise native creative localization and does not infer it from language targeting. list_creatives returns the original ID for Scope3-synced creatives and keeps unmapped provider-native images/videos visible under their provider IDs. It exhausts uploaded media, assigned ads, performance pages, and advertiser-authorized AUTH_CODE TikTok VIDEO rows before claiming a complete result. A missing connection identity, a cross-account or inactive mapping, stale provider media, or malformed, expired, or unauthorized Spark reference stops the operation before campaign creation. Only explicit, provider-authorized AUTH_CODE rows are accepted; missing identity types, legacy identity types, carousel rows, revoked authorization, and missing provider authorization start times fail closed. The stored Spark post and advertiser-bound identity must match the active provider generation. Uploaded media must read back as displayable before campaign creation. Channel accounts use a deterministic key over the advertiser and exact AUTH_CODE identity, so distinct grants remain isolated. A completed older creative generation cannot report unchanged or become active after a newer generation exists. Its historical assignment, review, and performance evidence remains joined to the active source creative. Each newly created TikTok ad remains paused while Scope3 requests its explicit creative fields. The exact uploaded media ID and format, or the exact Spark post ID and AUTH_CODE identity, must read back before activation; a missing or substituted creative triggers campaign cleanup. Media-library displayability and Spark authorization do not prove ad review: an unassigned creative remains processing. Explicit assigned-ad readback supplies approval or rejection status plus package and redacted provider-status evidence. Approval requires every assignment to be explicitly delivering or completed. Audit denials, partial approval, Promote audit failure, and terminal transcode failure are rejected; paused, pending, partial-review, budget, schedule, account, and asset-lifecycle states remain processing. Unknown provider statuses fail closed. Assignment inventory is mandatory; any incomplete page or transport failure fails the read. Scope3 verifies that each assignment and review-evidence row belongs to the selected TikTok advertiser; foreign or malformed evidence fails the read rather than changing a creative’s assignment or review state. TikTok’s AUTH_CODE endpoints do not return post publication time. A Spark row synced through Scope3 uses its durable registration timestamps. A provider-native authorized row uses TikTok’s UTC authorization start as its creative-availability timestamp and labels that basis in extension evidence; authorization timestamps are not presented as post creation or modification time. TikTok timestamps must use the documented UTC form or explicitly zoned RFC3339; numeric epochs, date-only values, offsetless ISO strings, and invalid calendar dates are rejected. Existing TikTok connections must remain connected through Settings > Connections and grant TikTok Posts Management query access so Scope3 can verify AUTH_CODE authorization before writes. Provider-native creatives that were not synced through Scope3 remain visible, but are returned under their provider ID with the explicit meta_unmapped_provider_creative format. Scope3 does not infer an upload format or reconstruct a source-media URL that Meta does not return. After a synced creative is updated, assignment, review, and delivery reads include every retained provider generation while returning only the current source creative. List cursors are account-, filter-, and snapshot-bound; restart pagination when the provider inventory or requested delivery snapshot changes. Scope3 discovers the Facebook Pages authorized for the selected ad account. If there is exactly one, page_id may be omitted and Scope3 selects it. If there are several, validation returns bounded page_id and Page-name choices without writing. If more choices remain, repeat the request with the returned ext.meta_page_selection_offset to page through them, then include the chosen page_id. Include instagram_actor_id only when the ad should use that authorized Instagram identity; explicit Page and Instagram IDs are validated against the selected account before any upload or creative write. Use the legacy Meta format_id returned by list_creative_formats. Image and video inputs must satisfy that format’s file type, dimensions, aspect ratio, duration, size, text, and link requirements. Public HTTPS URLs remain accepted. The portable Meta upload tool in supported MCP hosts instead returns a private, account-bound scope3-asset:// reference; sync_creatives exchanges that stable reference for a short-lived provider delivery URL without exposing the private object publicly. Scope3 validates required roles and request metadata before writing. For public image URLs it also pins public DNS, rejects redirects, caps downloaded bytes, and verifies JPEG/PNG content; Meta performs the final provider-side media processing. Portable upload availability depends on the Storefront environment having its private asset store configured. sync_creatives.assignments supports one meta_image_feed creative assigned to one existing paused package. Scope3 verifies that the package and its campaign belong to the selected account and are paused before creative writes, creates a paused Meta ad, records that provider ad before checking the package collection, and requires exact provider ad, creative, account, campaign, package, and paused-status readback. Retries reconcile the recorded ad instead of creating another one. Only that fully proven result returns the package in assigned_to with ext.manual_action_count: 0; ambiguity or drift is returned in assignment_errors without a zero-manual claim. Assignment during create_media_buy remains supported too. Sync-time assignment is a separate post-create operation; the canonical buyer lifecycle does not infer creative or actor selection from a campaign plan. Carousel child attachments, native Meta translation/localization, assignment weights, placement-specific assignments, multiple sync-time assignments, and creative deletion are not currently supported. Generated formats without a provider build-and-readback path are not advertised. Callers should not treat a successful upload as evidence that native localization ran, that provider review completed, or that no Ads Manager follow-up is required. Empty unsupported option collections are accepted as no-ops, but non-empty unsupported mutations fail before any provider write. Localization hints, including a raw Meta asset_feed_spec, also fail before Page discovery, media upload, or durable creative reservation instead of being silently removed from an otherwise valid creative. Meta’s current manual multi-language representation uses an asset_feed_spec with optimization_type: "LANGUAGE": bodies, titles, descriptions, links, and media carry labels, asset_customization_rules bind those labels to Meta locale keys, and exactly one rule is the default. Supported keys come from Meta’s /search?type=adlocale response. Scope3 does not pass this provider object through until the request has a typed AdCP representation and every requested locale, copy/media asset, Page/Instagram actor, provider creative, and provider variant label can be read back exactly. Dry runs read durable idempotency state and provider readback where needed, and perform no provider or ledger mutation.

Agency setup

The client adds the agency’s Business Manager as a Partner on the ad account — in Business settings, under Partners, using the agency’s Business Manager ID — and assigns the same scoped access described above (campaign management plus performance reporting, plus Page, pixel, or catalog assets as needed). The agency then connects its own Business Manager login in Interchange; every client ad account the partner grants reach arrives under the agency’s Business Manager on the Advertiser mapping tab, ready to map to the right advertiser.

Supported buying types

Interchange creates all Meta campaigns using the Auction buying type. Reservation (Reach & Frequency) buying type is not supported.

Meta app-install readiness

For Meta app-install campaigns, plan the campaign around mobile-first creative and privacy-safe app-event measurement before scaling spend:
  • Use Advantage+ App Campaigns as the default starting structure unless the advertiser has a specific manual-buying reason.
  • Start with lowest-cost bidding while the campaign is learning; move to cost controls only after the account has stable cost and conversion history.
  • Keep placements open across Feed, Stories, and Reels so Meta can allocate delivery, and design Reels-ready vertical creative rather than treating Reels as an afterthought.
  • Launch with at least 5-10 distinct creative variants. Prefer short vertical video that shows the app experience quickly, then keep refreshing variants as the campaign learns.
  • For iOS, confirm SKAdNetwork or MMP postbacks and Conversions API event forwarding before scaling. Evaluate D7/D30 cohort ROAS instead of day-1 last-click results.
  • Once trial, purchase, subscription, or other downstream app events are flowing reliably, optimize toward those events rather than raw installs.

TikTok

Ask the customer to share the advertiser account from TikTok Business Center to Scope3’s Business Center as a partner. Default grant for activation:
  • Advertiser account role: Operator.
Use Analyst only for reporting-only access. Analyst can view ads, performance, and reports, but it cannot create or edit ads or manage audiences. Use Admin only when there is an explicitly approved reason to manage ad account settings. Admin is not the default activation role. TikTok fixes an ad account’s currency when the account is created. Interchange reads that currency directly from the selected advertiser for product pricing, campaign creation and budget or bid updates, account financials, media-buy inventory, and delivery. If TikTok returns another advertiser, omits a requested account, reports an unknown account status, or returns malformed balance, timezone, identity, or currency data that conflicts with the selected account or accepted product, Interchange stops before a campaign budget or bid mutation. It never substitutes USD or combines money from different advertiser currencies. TikTok’s approved status is shown as active, its closed status is shown as closed, and its recognized review, verification, punishment, audit, authorization, and contract states are shown as suspended. Unknown or missing status and role values fail closed. Account discovery returns the complete accessible TikTok account inventory when pagination is omitted. Clients that request pages receive accounts in a stable order and must follow the opaque continuation cursor until has_more is false. Continuations are valid only for the same connection, filters, and provider snapshot; expired, changed, or modified cursors fail and must be restarted. Status filters are supported. TikTok does not identify these OAuth advertiser grants as sandbox accounts, so sandbox: true returns no production accounts. Additional assets may be needed depending on the campaign:
  • TikTok account delivery access for Spark Ads.
  • Use “Only show as ads” when Scope3 should be able to run Spark Ads without publishing posts to the TikTok profile.
  • Use “Show on TikTok profile and as ads” only when organic profile publishing is explicitly intended.
Scope3 does not need Business Center Admin, finance roles, or permission to add, edit, or delete users.

TikTok catalog sync

Interchange syncs a catalog only after TikTok confirms that the selected advertiser owns it and returns the complete catalog and feed inventory. The sync stops without changing the TikTok catalog if TikTok returns inventory from another advertiser, omits a page, or returns duplicate or malformed catalog or feed records. Interchange does not fall back to another advertiser or treat a partial inventory as complete. If a catalog that previously synced now fails, confirm that the connected TikTok advertiser owns the catalog and that TikTok can return its complete feed inventory, then retry. This buyer-side check does not change seller storefront setup, ranking, inventory labels, or any other buyer-visible seller information. Every TikTok campaign package must include a supported ISO country, either in the package targeting or its offering geography. Interchange stops before creating a campaign when a country cannot be mapped or when the request includes regions, unresolved interest themes, or another targeting dimension that TikTok cannot yet apply and read back exactly. It does not silently broaden delivery. For supported targeting, Interchange explicitly disables TikTok’s smart audience and interest expansion, then reads the new paused ad group back before adding creatives or activating delivery. If TikTok returns different country, age, gender, audience, frequency, or expansion settings—or the readback belongs to another advertiser—the campaign is not reported as successfully created and cleanup is requested. After that paused readback, Interchange records the exact requested targeting, TikTok confirmation, concrete product, advertiser, and provider ad-group identity in tenant-isolated durable state. Subsequent campaign reads return the provider-neutral requested and current targeting plus an exact-match result. An Interchange-created campaign fails closed if a provider-returned ad group loses that provenance or its targeting changes unexpectedly. TikTok-native campaigns remain readable without an Interchange request claim, and stale provenance is ignored only for ad groups TikTok has authoritatively removed. Terminal campaign deletion also removes the durable targeting record.

Agency setup

The client shares each advertiser account from their TikTok Business Center to the agency’s Business Center as a partner, using the agency’s Business Center ID, and assigns the Operator role (the same role guidance as above). The agency connects its own Business Center login in Interchange; the shared advertiser accounts appear grouped under the agency’s Business Center on the Advertiser mapping tab — map each to the right advertiser. Ask the customer to grant Scope3 manager-account or account-level access to the Google Ads account that will run the campaign. Default grant for activation:
  • Campaign management access.
  • Reporting access.
Additional access may be needed depending on the workflow:
  • Customer data or data-manager permissions when first-party audiences, enhanced conversions, or similar measurement workflows are enabled.
  • Conversion action access when Scope3 is expected to configure or send conversion events.
Scope3 does not need Google Ads account ownership, billing administration, or permission to add, edit, or delete users. For a mapped advertiser account, campaign inventory includes active, paused, and removed campaigns plus their ad groups (or Performance Max asset groups). Scope3 rejects the inventory read if Google returns an incomplete or cross-account hierarchy; it does not silently present a partial account mirror. For Search, Display, Performance Max, and Demand Gen campaigns, every returned revision is derived from the complete provider campaign and child state. Updates reject stale revisions before writing, then read back pause/resume, seller-package budget, supported ad-group bid, and advertiser-local schedule changes from Google. If one part of a multi-entity update fails, Scope3 restores the prior state or verifies that the campaign is paused before returning the error. Cancellation pauses an active campaign first and is not reported as complete until Google returns the removed campaign in terminal history. Reporting-only Google campaign types return no write actions.

Agency setup

Google’s flow runs in the other direction: the agency sends a link request from its manager account (MCC) using the client’s ten-digit customer ID, and the client accepts it from their account’s access settings. The agency then connects the manager account login in Interchange; client accounts under the MCC are discovered through the manager grant and appear under it on the Advertiser mapping tab — the MCC itself is context only and can never run buys.

Snap

Ask the customer to connect the relevant Snap advertiser account through OAuth or the approved Snap account-sharing flow. Default grant for activation:
  • Ads management access.
  • Reporting access.
Additional access may be needed for profile-backed creative workflows or measurement. New and reconnected hosted Snap connections request both snapchat-marketing-api and snapchat-offline-conversions-api. Existing connections must reconnect in Settings > Connections before conversion measurement is available. snapchat-profile-api remains excluded unless Snap has allowlisted the Scope3 app for Public Profile API access; profile-dependent creative workflows remain unavailable until then. For Snap server-side website and offline conversions, select the ad account that owns the Pixel. Interchange reads every page of the account’s Pixel inventory, rejects malformed, duplicate, or cross-account rows, and lists every Pixel Snap authorizes. If the account has multiple Pixels, Pixel-optimized packages must select one event_source_id; conflicting selections, a missing Pixel, or a foreign ID stop before campaign creation. Setup code appears only when Snap returns a provider-issued snippet. The base Pixel inventory proves configuration and ownership, not signal quality. Before conversion delivery, Interchange rechecks Pixel ownership, preserves event IDs for deduplication, and forwards a supplied test-event code. Snap’s documented exact VALID receipt confirms successful event processing, so the confirmed batch count is reported as both received and processed. Matching, attribution, and reporting finalization remain separate and asynchronous. An HTTP success without the exact VALID receipt is treated as a failed batch. Provider response bodies and access tokens are not exposed in diagnostics. Mobile-app conversion delivery remains unavailable until Interchange can verify the Snap App ID and required app metadata. Scope3 does not need organization administration, billing administration, or permission to add, edit, or delete users. For brief-led discovery, include one clear objective, exactly one supported country, and at most one gender. Interchange returns no actionable product when a Snap brief is missing those decisions, contains competing or negated objectives, requests targeting exclusions or unresolved interests, includes prompt-injection language, or asks for an unverified localization, age, or creative capability. For selected accounts, clear briefs receive a reviewable strategy with Snap’s exact objective, optimization goal, targeting intent, and supported image or video format. After the deterministic safety check, Interchange reads the exact selected account and uses its currency for returned and stored pricing, then verifies the requested country against Snap’s complete cached read-only targeting inventory before model interpretation, account-history ranking, or product persistence. Briefs that need clarification make no provider request. Both clear briefs and an empty “return the complete available Snap catalog” request require a selected account. USD-authored advisory floors and static budget guidance are not relabeled: non-USD products use a zero floor and omit unsupported static guidance. Before campaign creation, Interchange rechecks the provider currency against any trusted account snapshot, declared media-buy currency, accepted product, and assisted-execution snapshot, and stops before a write when they disagree. Every campaign, package, offering, and bid amount must also convert exactly to Snap’s integer microcurrency within the safe range before creation. When an offering omits its own budget, Interchange splits the package’s integer micros in request order and gives any remainder micros to earlier offerings, preserving the exact total across retries. Live non-spend evidence is still required for each non-USD account used in production readiness review. An assisted Snap create accepts exactly the concrete product, pricing option, objective, optimization goal, country, age, gender, and pricing snapshot that was proposed and accepted. A changed or incomplete snapshot stops before a Snap write. The accepted package intentionally contains no inline creative, offering, or catalog input: Interchange creates it paused, then performs creative assignment through a separate fail-closed sync while it remains paused. After creating each ad squad, Interchange reads its targeting back from Snap and requires an exact normalized match before continuing. It records the requested targeting, Snap-confirmed targeting, concrete product, connection, advertiser account, campaign, and ad-squad identity together; if that durable record cannot be written, Interchange deletes the paused campaign instead of returning success; deletion is reported complete only after Snap’s terminal readback confirms it. Campaign reads use that durable record to populate each package’s productIds, requestedTargeting, providerTargeting, and targetingMatchesRequest fields. Only country, region, metro, postal, age, and gender values cross this API boundary. Interest and audience identifiers remain private, but changes to them still make targetingMatchesRequest false because equality is checked on the complete normalized Snap targeting. A durable record is visible only to its exact connection and advertiser account. An incomplete matching record fails the read instead of inventing product or targeting provenance. Snap creative discovery currently returns only full-screen 9:16 image and video formats. Both require a brand name and a headline of at most 34 characters. Images must be JPEG or PNG, exactly 1080x1920, and at most 5 MB. Direct-upload video must be MP4 or MOV, exactly 1080x1920, 3-180 seconds, and at most 32 MB. During sync_creatives, Interchange validates every downloaded file before creating Snap media or creatives. Media URLs must use HTTPS on port 443; redirects, private or transition network addresses, mixed public/private DNS results, oversized bodies, and mismatched file types fail before those Snap writes. Interchange keeps a tenant- and advertiser-scoped creative identity. Retrying the same buyer creative with the same assets returns its existing provider creative instead of creating another one. A changed creative becomes the new active generation while the prior provider identity remains retained as history, and creative listing continues to use the stable buyer creative ID with the original name, format, and assets you submitted. When sync_creatives assigns that source creative to a package, Interchange first confirms that the campaign and Ad Squad still belong to the selected Snap account and reads the buyer’s durable paused intent. It journals the assignment before creating the Snap Ad, so retrying after a lost response reuses the same exact provider Ad instead of creating another one. Ordinary get_media_buys reports Snap review state, provider creative identity, requested paused intent, provider campaign/package pause state, whether lifecycle intent is available, and whether those states match. If the intent store is unavailable, provider state remains readable but buyer intent and the match result are explicitly unknown; Interchange does not infer them from Snap. Exact source/media/creative/Ad materialization is available only to Scope3’s protected staging readiness check. That check also requires a future-dated paused campaign, a paused Ad, and zero delivery before it records readiness. Story, Collection, Lead Generation, Sponsored Snap, Commercial, generated, and promoted-offering formats are not currently advertised; stale selections fail before provider or media-source access. This discovery change does not edit, pause, or delete existing campaigns or provider creatives. They can continue delivering in Snap. If a connected account contains a creative in one of the unadvertised formats, Interchange leaves it in Snap and returns UNSUPPORTED_CREATIVE_FORMAT instead of showing an incomplete creative inventory. If Snap is still processing any creative media, creative inventory stays fail-closed and returns CREATIVE_MEDIA_NOT_READY. Retry after Snap finishes processing the media. Buyer-paused Snap campaigns stay paused after delayed creative assignment in both ordinary and protected paths. Only an explicit resume can change that intent, and resume is rejected until every live Ad Squad has a creative. Resume completes creative replacement and readback while paused, then activates each Ad, each Ad Squad, and the Campaign in that order. The explicit resume is recorded durably after preflight so a process restart can finish it safely. A failed or ambiguous resume is contained back to paused state and restores paused intent before the error returns. Campaigns created before durable lifecycle intent was introduced require one explicit pause or resume before another budget, schedule, or creative update; Interchange does not infer buyer intent from provider state. Before creating any ad squad, Interchange requires the new campaign to return and read back under the selected advertiser account as paused and not deleted. Each new ad squad must likewise return and read back under that campaign as paused and not deleted, including for paused requests. A campaign identity that belongs to another advertiser account is never paused or deleted; the request fails with an ownership-isolation error for operator review. Snap sometimes communicates a rejected operation inside an HTTP success response. Interchange accepts a media-buy or control-plane single-entity read or write only when both Snap’s request and its one entity result report success and the returned identity and parent scope match the requested object. Snap’s campaign and ad deletions use the provider’s documented empty acknowledgement, followed by a required terminal readback. Otherwise Interchange stops before the next lifecycle step and returns a fixed error category with a Scope3-generated correlation ID. Snap request IDs, messages, debug text, and identifiers are not returned or logged. Public Profile selection follows every canonical Snap Business API page and stops if the complete inventory does not identify exactly one usable profile. Before mutating a global campaign, ad-squad, or ad ID, Interchange reads its parent chain back to the selected advertiser account. Creative assignments preflight every target package through the same chain before media or creative writes. Media upload must acknowledge the allocated media ID before polling, and bid estimates must match the requested optimization goal with a valid numeric range before use. Native catalog creation derives its organization from the selected Snap account rather than request context, requires that account’s currency, and maps the catalog to a supported Snap vertical. Interchange stores complete native catalog inventory as a durable pre-write baseline before creating anything. Selected-account and currency checks complete before the create is reserved, so a failure before the POST can be corrected and retried. A first sync never adopts a matching catalog created manually in Snap. If the create response is lost or ambiguous, retries remain read-only and may recover only one matching catalog that was absent from that baseline; they never send another create request. Missing or multiple new matches stop safely for a later retry. The durable boundary requires a stable connection credential or principal, uses the host credential key or client identity rather than optional metadata, and never uses the rotating OAuth access token or a non-durable direct-call fallback. Catalog data and delete-missing changes remain staged until provider checks and conflict arbitration succeed. The final account mapping update is atomic and revision checked, so a stale concurrent delete-missing request changes nothing. Retrying reuses a completed Snap create rather than posting another catalog. The complete source catalog participates in conflict detection, so concurrent configurations cannot overwrite the winning mapping. Stored offering and job catalog references must be non-empty, well formed, and belong to the same connection and selected account before Snap receives a request. Catalog data, Snap identities, discovery, and delete-missing behavior remain isolated when connections share an account or catalog ID. A Snap identity is reused only from that connection’s completed journal and must still match the selected organization, name, and catalog type. Feed creation revalidates the catalog’s organization against that account and sends Snap’s required catalog, currency, URL, and schedule fields. Interchange retains the Snap catalog identity before feed setup, so retrying after a rejected or lost feed response reuses the same catalog. An already-created feed is reused only when its complete paginated readback exactly matches the effective requested name, currency, URL, and interval. Snap may omit documented primary, active, UTC, interval-count-one, or minute-zero defaults from a response; Interchange normalizes those defaults before comparison. Explicit drift or ambiguous inventory stops without another provider write. Feed creation has its own connection/account/catalog-scoped durable journal. If an accepted feed is not yet visible after a lost response, every retry stays read-only until the exact feed appears. When catalog_ids selects only part of a request, unselected catalogs create no Snap object, feed, journal, or local mapping. If a later Ads or Business API inventory page fails at the HTTP, provider, or sub-request layer, Interchange returns an incomplete-inventory flag and correlation ID instead of returning the successful prefix. The legacy endpoint uses INCOMPLETE_PAGINATION; the standard SDK endpoint uses SERVICE_UNAVAILABLE. A short enum-shaped provider code may be included; provider text and identifiers are withheld. These guarantees apply to the campaign, ad-squad, ad, creative, media-upload, bid-estimate, Public Profile, Pixel, and catalog client methods covered here. Audience batch/poll and Conversions API HTTP-success provider-envelope handling remain separately tracked work; this is not a universal claim for every Snap endpoint. For an unpaused request, Interchange activates and verifies each ad squad while the campaign remains paused, then activates and verifies the campaign last. A fresh provider read must still match the expected parent campaign or advertiser account immediately before each activation PATCH; ownership drift or a deleted row sends no PATCH. Provider identity and status must match at every readback, and deleted tombstones never satisfy a live status. For any post-campaign-create failure after advertiser ownership is validated—including a thrown creative or profile operation—Interchange first requests paused containment and reads the campaign back, then requests deletion. It reports rollback only after Snap confirms the terminal deleted state. If any intervening readback belongs to another advertiser account, Interchange stops before another provider mutation and raises an ownership-isolation error. Drift discovered after campaign activation triggers only a selected-account-scoped paused-containment attempt; if ownership cannot be recovered, the fatal response says the campaign may still be active and requires operator review. This also applies when campaign activation returns an error or its active-state readback fails, because Snap may have applied the activation. Rejected provider-client promises follow the same cleanup path. Once another advertiser account is observed, a later provider error cannot proceed to DELETE until exact selected-account ownership is seen again. An exact already-deleted selected-account readback confirms rollback without another DELETE. When Snap cannot confirm deletion, the response says whether paused containment was confirmed or whether the campaign may still be active; it never describes an unconfirmed deletion as complete. Every Snap package or offering must currently resolve to one supported ISO country; UK is normalized to GB. Before creating a campaign, Interchange checks that country against Snap’s complete current targeting inventory, cached for 24 hours. A missing, empty, malformed, or unavailable inventory stops the request. Five-digit US ZIP targeting is supported. Interchange rejects regions, device form factors, standard audience include/exclude fields, non-US postal systems, unknown products, incompatible campaign-objective mixes, and other targeting it cannot represent exactly before creating the campaign. Product targeting may use Snap’s exact age buckets, one gender, discovered SLC interest IDs, and discovered Snap audience IDs. Per-individual frequency caps support a maximum 30-day window on compatible Snap optimization goals. Interchange also sets Snap’s interest and custom-audience expansion controls to disabled so the provider does not silently broaden those accepted targets. First-party Customer Lists are isolated to the Interchange connection and selected Snap advertiser that created them. Interchange records a durable buyer-to-Snap audience identity before writing, validates Snap’s exact add and remove receipts, and confirms deletion only after Snap no longer returns the segment. Each request carries one identifier type and at most 100,000 hashed identifiers; an audience reports only counts confirmed by Snap’s exact receipts, including earlier confirmed batches if a later batch fails. The same normalized identifier cannot be added and removed in one request. Name and description changes are read back from Snap before Interchange reports them complete. Hashed identifiers and provider text that could echo them are excluded from logs together with request paths, bodies, and provider response data. Member-write errors similarly replace provider and transport text with fixed host-owned semantics. Polling accepts buyer audience IDs only and fails as a whole if any requested status cannot be verified. Post-add/post-remove readback preserves Snap’s pending, paused, upload, and targetability states but does not present Snap’s approximate size as an exact match count. A lost or ambiguous provider response is reported as reconciling and does not trigger a duplicate create. If a connection has no durable private identity, audience access fails closed and asks you to reconnect it. Audience types and tags that Snap cannot preserve are rejected before a provider request. Snap recognizes only the documented audience source types. Known sources that are not first-party Customer Lists remain outside Customer List discovery; an unknown or malformed source fails the complete read instead of disappearing silently.

Agency setup

Snap access is member-based: each client invites the agency’s user into their Snap Organization as a member with an ad-account role that can manage campaigns and read reporting. The Snap grant is tied to the authorizing user, so the agency connects that user’s own Snap login in Interchange — the connection discovers every ad account the login can reach across all client Organizations, grouped by Organization on the Advertiser mapping tab.

LinkedIn

Ask the customer to connect the LinkedIn ad account that will run the campaign. Default grant for activation:
  • Ads read access.
  • Ads write access.
  • Ads reporting access.
Additional access may be needed when creatives or sponsored content require an organization identity. Scope3 does not need Company Page administration unless the agreed workflow includes organic or organization-social publishing. Scope3 does not need LinkedIn account ownership, billing administration, or permission to add, edit, or delete users.

Agency setup

Each client adds the agency’s user to their LinkedIn ad account with a role that can manage campaigns and read reporting (Account Manager, or Campaign Manager when scoped to campaign work); a Sponsored Content Poster grant on the client’s Page is only needed when ads run under the Page’s identity. The agency connects its own LinkedIn login in Interchange; every client ad account the login can reach is discovered on the Advertiser mapping tab — map each to the right advertiser. Connected-account campaign reads enumerate LinkedIn’s complete cursor-paginated campaign and creative inventory and fail closed if LinkedIn cannot prove a complete account-scoped snapshot. This connection is a read-only mirror; an account appearing here does not authorize Interchange to mutate its campaigns.

Pinterest

Ask the customer to connect the Pinterest ad account that will run the campaign. Default grant for activation:
  • Ads read access.
  • Ads write access.
Additional pin read/write access may be requested when the campaign workflow uses Pinterest-native creative or pin objects. Scope3 does not need account ownership, billing administration, or permission to add, edit, or delete users.

Agency setup

The client shares the ad account with the agency’s business through Pinterest business access — adding the agency as a partner by its business ID and assigning an ad-account role that can manage campaigns and read reporting. The agency connects its own Pinterest business login in Interchange; shared client ad accounts are discovered on the Advertiser mapping tab — map each to the right advertiser.

Reddit

Ask the customer to connect the Reddit Ads account or profile that will run the campaign. Default grant for activation:
  • Ads read access.
  • Ads edit access.
Additional conversion permissions may be requested when the customer enables conversion tracking or event logging. Interchange reads the selected account’s Reddit Pixel inventory before showing setup instructions or sending server events. The Pixel ID comes from Reddit; the ad account ID is not used as a substitute. Server events use Reddit’s Conversions API v3 and are reported as processed only when Reddit confirms the entire submitted batch. If a Pixel is missing, belongs to another account, or cannot be resolved to one account, the operation stops before sending events. Website and app sources keep their native Reddit categories. In-store events use Reddit’s physical-store category; broader offline or CRM events use Reddit’s OTHER category because v3 does not accept an OFFLINE value. Customer-list audiences accept SHA-256 email addresses and mobile advertising IDs. Interchange binds each created list to the connected customer and ad account, so retries and buyer/provider ID aliases reuse the same Reddit audience and operation lock. A provider audience created by another connected customer cannot be changed or deleted through its raw Reddit ID, even when both connections can access the same ad account. Lists not created by the current Interchange connection remain visible but read-only. Adds and removes are set operations. uploaded_count reports add rows accepted by Reddit, not matched users; audience size and match readiness come from later provider status. A failed delete or remove is returned as failed rather than successful. Reddit does not return partner ad accounts when an integration enumerates a Business. Account-selected Pixel discovery still works for those accounts, but server-event logging without an account reference fails closed until the Pixel can be bound to one accessible account. Scope3 does not need Reddit account ownership, profile administration beyond the advertising workflow, or permission to add, edit, or delete users.

Agency setup

Each client invites the agency’s user into their Reddit Ads Business as a member with access to the relevant ad account and a role that can manage ads and read reporting. The agency connects its own Reddit login in Interchange; the client ad accounts the login can reach are discovered grouped under their Business on the Advertiser mapping tab — map each to the right advertiser.

Spotify

Ask the customer to authorize Spotify with a user who can reach the Business and advertiser ad account that will run the campaign. Default grant for activation:
  • Campaign and ad-set management access.
  • Reporting access for the selected advertiser account.
The Spotify adapter can pause or resume a campaign and update package budgets, bids, end dates, and delivery state through the canonical buyer media-buy lifecycle. Its protected canary queries products, creates a future-dated buy, pauses it immediately, verifies readback, performs a bounded package-budget decrease, and confirms the result through the same buyer APIs used by regular traffic. Spotify does not expose an irreversible campaign cancellation operation: use pause to stop delivery, and expect a cancellation request to return unsupported rather than permanently deleting the campaign. Configure Spotify Pixel and Conversions API sources in Spotify Ads Manager. Interchange discovers only sources delegated to the selected advertiser account and does not create a new source against an unverified dataset. Spotify Pixel is a browser installation managed in Spotify Ads Manager; Conversions API is the server-side source. Customer-list discovery and reconciled deletion are available. Customer-list upload and replacement are currently unavailable because Spotify’s published Ads API does not provide the CSV and retry-recovery contract needed to make those writes safe. Conversion-event ingestion is not currently advertised: the shared request cannot select an advertiser account for Spotify’s multi-account OAuth connection, and Spotify does not document authoritative success semantics that make retries safe. Calls fail before provider I/O. Scope3 does not need Spotify Business ownership, billing administration, or permission to add, edit, or delete users.

Amazon Ads

Ask the customer to connect the Amazon Ads account that will run the campaign. Default grant for activation:
  • Advertising campaign-management access.
  • Reporting access.
Amazon retail, seller, or vendor account administration is separate from advertising campaign management. Scope3 does not need retail account ownership, billing administration, or permission to add, edit, or delete users.

Agency setup

Each client invites the agency’s user to their Amazon advertising account from the Amazon Ads console’s user management, with a role that can manage campaigns and read reporting (DSP entities manage their users separately). Amazon access follows the Login with Amazon user, so the agency connects its own Amazon login in Interchange; every Sponsored Ads profile and DSP advertiser the login can reach is discovered on the Advertiser mapping tab. Amazon has no manager container — accounts arrive as a flat list, typed sponsored_ads or dsp.

Revoking Access

Customers can revoke Scope3’s access from the platform’s business, partner, manager-account, or OAuth settings. Revoking access stops future discovery, campaign changes, creative sync, audience sync, catalog sync, reporting reads, and measurement writes for that connected platform account. After revocation, refresh the connection in Interchange before running new discovery or media-buy workflows so the account status reflects the provider’s current authorization state.