VoidhashDocs
DevelopersHelp centerGuidesAPI reference
Dashboard
Get started
Introduction
Quickstart
How Voidhash works
Glossary
Versions and releases
Concepts
Teams, projects and environments
API keys
Products and perks
Offers
Subscription lifecycle
People and identity
Events
Features
Paywalls in your app
Feature flags and A/B tests
Paywall components
Push notifications
Ad attribution in your app
Client SDKs
React Native
Swift
Kotlin
Web
Your backend
Node.js
PHP
Go
Rust
Other languages
Payment sources
Forward store notifications
Developer tools
CLI
MCP server
Query analytics with VoidQL

Ad attribution in your app

What the SDKs record about where people came from, what Voidhash sends to Meta, and how to automate ads.

Voidhash credits each signup, and everything the person pays later, to the ad or campaign that brought them, from data your SDKs record. This page covers the code; Ad measurement in the Help center covers the reports in Studio.

What your app needs

  • The web SDK on your landing pages and web app, and a mobile SDK in your apps.
  • identify with the same user ID wherever people sign up or sign in. That ID links a web visit, an app install and purchases on any store. See People and identity.
  • Campaign parameters on your ad links, such as the Meta URL parameters.

Where touches come from

A touch records where a person came from, with an ad network when it came from an ad. Each SDK writes touches to the person as $initial_… and $latest_… traits.

SourceWhat the SDK readsDetails
Web pagesutm_* parameters, campaign_id, adset_id, ad_id, click IDs such as fbclid, gclid and ttclid, and Meta's _fbc and _fbp cookies.Campaign attribution
iOSThe Apple Ads attribution token, once per install.Credit installs to Apple Ads
AndroidThe Google Play install referrer, and with metaAppId, Meta's install referrer for installs from Meta ads.Credit installs to ad campaigns
Web to appA website visit followed by a sign-in in your app with the same user ID.Web to app

React Native runs the iOS and Android behavior; see Install attribution. Touches need analytics consent. Only ad spend needs a connected ad account; attribution works for every network.

Share purchases with Meta

Voidhash can send production purchases to Meta's Conversions API, so Meta counts renewals and purchases its pixel and SDK miss. Sending a person's purchases needs their agreement, which is separate from analytics consent. Record it with setAdDataSharing:

try await voidhash.setAdDataSharing(true)
voidhash.setAdDataSharing(true)
await voidhash.client.setAdDataSharing(true);
await voidhash.setAdDataSharing(true);

The call sets the $ad_data_sharing person attribute:

  • Only the Boolean true counts. The text "true", set through setPersonAttributes, doesn't.
  • Agreeing needs analytics consent. setAdDataSharing(false) always goes through, and the SDK retries it for up to 48 hours. Declining analytics doesn't revoke the agreement, so when someone rejects everything, call both.
  • When two profiles of a person merge, a false on either one wins.
  • A true set within 5 minutes after a false is ignored. Ask again later.
  • false stops sending from then on. What Meta already received stays with Meta, including after you delete the person's data.

On iOS, sending someone's purchases to Meta can count as tracking under Apple's rules. Check whether you need App Tracking Transparency permission before you call setAdDataSharing(true).

What Meta receives

Each purchase is a Purchase event with its time, amount and currency, and:

FieldValue
event_idtransaction:<id>, so Meta counts a purchase once even if it arrives twice.
action_sourcesystem_generated for renewals, other otherwise.
emA SHA-256 hash of the person's email, when known.
external_idA SHA-256 hash of the user ID you identified them with. Anonymous IDs aren't sent.
fbc, fbpThe person's $fbc and $fbp, or an fbc built from the fbclid of the credited Meta ad click.

Voidhash doesn't send purchases without an email, fbc or fbp; free trials; refunded or revoked purchases; purchases of erased people; or purchases older than 7 days. If you also send purchases to Meta from your own code, they have other event IDs and count twice, so send them one way.

Delivery runs every 15 minutes and leaves each purchase 5 minutes to settle, so a purchase usually reaches Meta within 20 minutes. Each run sends up to 5,000 purchases in up to 64 requests. A purchase reported before its price is known waits up to 1 hour for the store's server notification, then is skipped. Set up the dataset and token in Studio; see Send purchases to Meta.

Automate from the CLI and API

TaskCLIAPI or MCP
Connect a Meta ad accountvoidhash ads connect act_1234567890 --token-stdin --backfill-days 365ad_accounts.create with platform, externalId, accessToken and backfillDays
Set up the Conversions APIvoidhash ads measurement edit --dataset 1234567890 --token --enablemeta_measurement.updateSettings, set_meta_conversions
Store the install referrer decryption keyvoidhash ads measurement edit --install-referrer-keymeta_measurement.updateSettings with installReferrerKey
Set the attribution window (1–90 days)voidhash settings set ads-attribution-window-days 14projects.updateSettings with ads.attributionWindowDays
Set the key conversionvoidhash settings set ads-key-conversion trialprojects.updateSettings with ads.keyConversion: signup, trial or payer
Mark landing pages as web-to-appvoidhash ads settings web-to-app example.app/startads.updateSettings with webToAppLandingPrefixes, set_web_to_app_prefixes

Tokens and keys are read from a hidden prompt or standard input, never from a flag's value. Connecting an account that is already connected replaces its token; --backfill-days imports up to 1,095 days. Ad accounts, measurement and web-to-app prefixes need project:ads:manage; the attribution window and key conversion need permission to update the project. See CLI: ads.

Reports

The performance, creatives and cohorts reports and ads issues are in the API, the CLI and the MCP tools. They take currency, timezone and environment, and need project:ads:read; measured people and revenue also need project:analytics:read, or come back empty.

The changes report and the ads_changes_report MCP tool show what changed between hourly syncs over up to 7 days (the MCP tool defaults to the last 24 hours):

  • Decisions: campaigns, ad sets and ads created, turned on, paused or removed, and budget and bid strategy changes, with values before and after. Name, targeting and creative edits aren't recorded.
  • Delivery: what each campaign, ad set or ad spent, showed, got clicked and converted between syncs.
  • Revisions: Meta's corrections to days that had already ended, mostly late conversions.

Amounts are Meta's, in minor units of each ad account's currency and time zone. historySince says when history starts for each account.

Next steps

  • Page views and attribution: the web SDK's campaign rules.
  • Web to app: carry a website visit into your app.
  • Ad measurement: how Studio credits signups and revenue.
  • Connect Meta Ads: connect an ad account in Studio.

Something wrong or missing on this page? Tell us by email or on Discord.

PreviousPush notificationsNextReact Native SDK

On this page

What your app needsWhere touches come fromShare purchases with MetaWhat Meta receivesAutomate from the CLI and APIReportsNext steps