Skip to main content

Overview

AppDNA can receive webhooks from billing, attribution and messaging providers. Each authenticated delivery is stored and converted into AppDNA’s canonical events with source: "<provider>". RevenueCat has its own page: RevenueCat.
Mappings are enabled per provider after a confirmed real delivery. Authentication works for every provider below today. Each provider’s event mapping — other than RevenueCat’s — is switched on only after a real delivery from that provider has confirmed its payload. Until then, authenticated deliveries are stored, not counted; they are kept without the URL token and without the personal fields AppDNA removes for that provider — Adapty: e-mail, phone number and user attributes; Superwall: user attributes other than appdna_user_id; CleverTap: profile e-mail, phone, name and push token; AppsFlyer and Singular: IP address; Adjust and Pushwoosh: nothing is removed — and are replayed into analytics once the mapping is enabled.
Provider events count for revenue, not for activity. Provider events count for revenue, lifetime revenue and attribution. They never count as sessions, active users, retention or billable MAU — those come only from the AppDNA SDK running in your app. Purchases and renewals from a billing provider (RevenueCat, Adapty, Superwall) do count toward MTPU (monthly tracked paying users), once per user after de-duplication with SDK purchases. Once a billing provider reports a subscription, its renewals are counted from the provider only; the SDK’s device renewal for that subscription adds no revenue.

How each provider counts

  • One purchase, one count. When several sources report the same store transaction, AppDNA keeps one, by precedence RevenueCat > Adapty > Superwall > the AppDNA SDK > events you tracked yourself.
  • Do not track canonical purchase or attribution event names yourself with AppDNA.track when the corresponding webhook is connected; use custom names for your own UI analytics.
  • Events from a messaging or attribution provider never trigger AppDNA journeys or e-mail automations. Billing-provider purchases do, like SDK purchases — except replayed events (deliveries stored before the provider’s mapping was enabled), which never trigger journeys or e-mail automations.
  • When several attribution providers are connected, AppsFlyer > Adjust > Singular decides a user’s attribution.

Authentication and secrets

Each provider uses one of three mechanisms. The integration page shows the right controls.
  • Reveal, Copy and Rotate are owner-only. The Authorization value, or the tokenised URL, is masked on the integration page; only the organisation owner can reveal, copy or rotate it. Right after an admin connects an integration, the connect dialog shows the plain URL and, for the owner, the credential once. Rotating invalidates the old credential immediately — paste the new one into the provider.
  • Superwall has no AppDNA-generated secret: paste Superwall’s signing secret (whsec_…). It can be replaced, not removed. Signatures older than 5 minutes are rejected.
  • Failed authentication returns 401. The reason is logged on AppDNA’s side, never the secret.
  • Disconnected integrations drop deliveries. While an integration is disconnected, authenticated deliveries are answered with 200 (so the provider does not retry for hours or disable the endpoint) and discarded. Reconnecting keeps the existing secret.

Pass the AppDNA user id to each provider

AppDNA links a provider event to your user through the id you pass to AppDNA.identify. Give each provider the same id: Events from a user the provider does not yet know are stored and counted under a pseudonymous placeholder, and are linked to the user when a later event from the same provider carries the id.

Provider setup

Adapty (billing)

  • In Adapty → Integrations → Webhooks, paste the AppDNA webhook URL into both the production and the sandbox endpoint fields, and paste the same Authorization value Bearer <secret> into both the production and the sandbox Authorization fields. Adapty’s verification request on Save succeeds.
  • Sandbox events (environment: Sandbox) go to AppDNA’s sandbox dataset.
  • If you renamed Adapty event ids, enter them under Renamed event IDs on the integration page so AppDNA recognises them.
  • Mapped events: subscription and trial starts → purchase_completed + subscription_started; renewals and trial conversions → subscription_renewed; renewal cancellations → subscription_canceled; expirations → subscription_expired; billing issues → subscription_renewal_failed; refunds → purchase_refunded; one-time purchases → purchase_completed.
  • With billingProvider: adapty, the AppDNA SDK keeps sending its device renewal and cancellation events; connect the Adapty webhook to add server-side renewal and refund data once its mapping is enabled — AppDNA then counts each event once.

Superwall (billing)

  • In Superwall → Integrations → Webhooks, add the AppDNA webhook URL, then copy Superwall’s signing secret into AppDNA’s Webhook signing secret (owner).
  • Mapped events: initial purchases → purchase_completed (+ subscription_started for subscriptions), renewals → subscription_renewed, cancellations → subscription_canceled, expirations → subscription_expired, billing issues → subscription_renewal_failed; any event with a negative price → purchase_refunded, and so is a cancellation with cancelReason: CUSTOMER_SUPPORT (Superwall’s refund carrier) — it becomes purchase_refunded (negative revenue), not subscription_canceled.
  • Superwall sends no test webhooks. Sandbox events go to the sandbox dataset.

AppsFlyer Push API (attribution-only)

  • In AppsFlyer → Integration → API access → Push API, set method POST, the AppDNA URL, token name Authorization and value Bearer <secret>.
  • Tick these fields: event_type, appsflyer_id, customer_user_id, media_source, campaign, af_c_id, af_adset, af_ad, af_channel, install_time, is_retargeting, is_primary_attribution, campaign_type, event_revenue, event_revenue_currency, event_revenue_usd, the af_cost_* fields, country_code, platform.
  • AppsFlyer’s “Send test” button gets 401 by design: AppsFlyer test messages carry no token. Test with a real install, or use a separate AppsFlyer app for test builds.
  • AppsFlyer has no sandbox flag; every delivery counts as production.

Adjust server callbacks (attribution-only)

  • Use the full URL from Reveal (it includes the token) as a global callback with method POST, and add the single-activity ad-revenue callback if you monetise with ads.
  • Include these placeholders in the body: activity_kind, created_at_milli, installed_at, environment, adid, idfa, idfv, gps_adid, os_name, app_id, store, country, event_token={event}, event_name, revenue_float, currency, revenue_usd, tracker, tracker_name, network_name, campaign_name, adgroup_name, creative_name, is_organic, is_reattributed, match_type, partner_parameters, plus the ad-revenue placeholders.
  • Add the global callback parameter appdna_user_id in your app (above).
  • Rotating issues a new URL — update it in Adjust.

Singular Internal BI postbacks (attribution-only)

  • Use the full URL from Reveal (it includes the token) as the postback URL.
  • Set the Singular custom user id to the AppDNA id. Deliveries whose fraud_status is not valid are stored, not counted.
  • Rotating issues a new URL — update it in Singular.

CleverTap Webhooks channel (messaging)

  • Create a webhook in CleverTap with method POST, the AppDNA URL, and on the Headers tab the key Authorization with value Bearer <secret>.
  • The appdna_event convention: a CleverTap webhook is a campaign call, not an event stream. To record a specific engagement event, add the key-value appdna_event to the webhook with one of push_delivered, push_tapped, email_sent, email_delivered, email_opened, email_clicked, email_bounced, email_unsubscribed, in_app_message_shown, in_app_message_clicked — for example on a Live-behaviour webhook triggered by “Notification Clicked”. Post Action webhooks record push_delivered; any other campaign webhook records messaging_campaign_sent for each targeted profile. Template tests (is_test) are stored, not counted.

Pushwoosh Event Streaming (messaging)

  • In Pushwoosh → Event Streaming, add the AppDNA URL and set the Authorization value Bearer <secret>.
  • Mapped events: Push Delivered → push_delivered, Push Opened → push_tapped, e-mail events → email_*, in-app shows and clicks → in_app_message_shown / in_app_message_clicked.
  • Pushwoosh batches events: expect up to 1 hour of latency.

Troubleshooting