Rovenue SDKBeta
Integrations

Advenue

Send store-verified purchases and subscription events from Rovenue to Advenue, so installs are attributed to the campaign that earned the revenue.

Advenue is an open-source mobile measurement platform. This integration sends Rovenue's store-verified revenue and subscription events to Advenue server to server, so Advenue can credit each purchase to the install and campaign behind it. Revenue comes from the store receipt Rovenue already verified, not from a client call, so it cannot be spoofed from the app.

Connect

  1. In Advenue, create a Rovenue secret for the project that holds your store listings. The secret starts with rvwh_ and belongs to that Advenue project.
  2. In the Rovenue dashboard, open Integrations, pick Advenue and paste the secret.
  3. Leave Endpoint empty on Advenue Cloud. Set it only for a self-hosted Advenue, to its base URL (for example https://advenue.example.com). Rovenue appends /v1/store/rovenue itself and refuses an endpoint that carries a query string or fragment, or that points at a private address.
  4. Press Send test. Rovenue sends a rovenue.ping, which Advenue shows in its delivery log as a test. A wrong secret reads "Advenue rejected the secret".

Identity: set $advenueId

Rovenue has to hand Advenue something that identifies the install. Copy the Advenue device id into the reserved $advenueId subscriber attribute (see subscriber identity attributes). The Advenue getters can return null before Advenue has started, so check it before you call Rovenue.

// iOS
if let id = await Advenue.deviceId() {
    try await Rovenue.shared.setAttributes(["$advenueId": id])
}
// Android, inside a coroutine
Advenue.deviceId()?.let { id ->
    Rovenue.shared.setAttributes(mapOf("\$advenueId" to id))
}
// React Native
import { Advenue } from "@advenue/react-native";
import { Rovenue } from "@rovenue/react-native-sdk";

const id = await Advenue.getAdvenueId();
if (id) await Rovenue.setAttributes({ $advenueId: id });
// Flutter
final id = await Advenue.getAdvenueId();
if (id != null) {
  await Rovenue.instance.setAttributes({r'$advenueId': id});
}

There is no Advenue web SDK. For web apps, pass the Advenue id from your own front end to your backend and set it with POST /v1/subscribers/:appUserId/attributes using your secret key (see the server-side API guide).

If a subscriber has no $advenueId, Rovenue falls back to the IDFA, but only when the subscriber's ATT status is authorized. Android advertising ids are never sent.

Events sent

Rovenue sends only the events below. Advenue maps them by type.

Rovenue eventAdvenue eventRevenue
subscription.trial.startedsubscription_started0
revenue.INITIALsubscription_converted (subscription) or iap_purchase (other products)+amount
revenue.TRIAL_CONVERSIONsubscription_converted+amount
revenue.RENEWALsubscription_renewed+amount
revenue.REACTIVATIONsubscription_renewed+amount
revenue.NON_RENEWING_PURCHASEiap_purchase+amount
revenue.CREDIT_PURCHASEiap_purchase+amount
revenue.REFUNDsubscription_churned (subscription) or iap_purchase (other products)−amount
subscription.expiredsubscription_churnednone

Revenue is the gross original amount and currency; Advenue converts it with its own exchange rates at report time. Rovenue does not send revenue.CANCELLATION, credit.* events, or other subscription events such as cancel requests, billing issues or grace periods. Churn is counted when a subscription expires, not when it is cancelled. Manually granted purchases are not store-verified revenue and are never sent.

Sandbox

Every event carries its environment. Sandbox and TestFlight purchases reach Advenue marked sandbox, so they never count as production revenue. If Rovenue cannot work out the environment of a purchase, it retries the delivery instead of guessing production.

Separate Advenue listings

Advenue groups the iOS and Android listings of one product into a project, and a secret belongs to that project. Rovenue picks the listing from the purchase store, so App Store sales land on the iOS listing and Google Play sales on the Android one.

If your iOS and Android apps are still separate Advenue projects, the recommended fix is to merge them in Advenue and use one Rovenue connection. Otherwise add one Advenue connection per Advenue project, each with its own secret.

In the dashboard, open Apps and use Add another connection on the pinned Advenue card. It runs the same steps as the first connection: the Advenue secret is required and the Endpoint is optional. Give each connection a Label, for example "Advenue — iOS project", so you can tell them apart. Every connection is listed on the card with its own Edit, and you configure or remove each one separately; the card shows Connected while at least one is enabled, plus the count when there are several. Each Advenue project keeps the events of its own listings and answers the others as ignored, which is expected.

A project can have up to 10 Advenue connections. Rovenue refuses a connection whose secret another connection in the same project already uses, because it would send every event to the same Advenue project twice.

A purchase made on a different device than the one that last wrote $advenueId still lands on the right listing, but it may not join that device's install.

Delivery log

Events Rovenue chooses not to send appear in the delivery log as skipped, with a reason:

ReasonMeaning
no_mappingThe event is not one Advenue receives, is skipped by an event override on this connection, comes from a manual grant, or its product has no store product id for that store.
filtered_by_event_scopeThe event was switched off on this connection after it was queued. An event that is already off when it happens is not queued and leaves no row.
no_user_dataThe subscriber has no $advenueId and no authorized IDFA, or was erased before the delivery. Set $advenueId as above.
invalid_revenueA revenue event had a missing, zero, negative or non-decimal amount, or a currency that is not three letters.

Failures that retrying cannot fix, such as a rejected secret (401) or a body Advenue refuses (400), go straight to the dead letters. Timeouts, rate limits and server errors are retried.

Attribution and Campaigns

The same connection also works the other way: Advenue tells Rovenue which ad brought each install, and lists its campaigns on Acquisition › Campaigns before their first install. You can then map a campaign to an onboarding funnel up front, and the first installs from it already see that funnel (see acquisition targeting). No SDK update is needed; everything runs server to server. It requires an Advenue release that sends the install.attributed webhook event.

What flows

DirectionWhatHow
Rovenue → AdvenueStore-verified revenue and subscription eventsEvents sent
Advenue → RovenueOne attribution per install Advenue attributes: network, campaign, ad set, adThe install.attributed webhook, posted to your project's Advenue URL and signed by Advenue
Rovenue ← AdvenueThe campaigns Advenue knows (the catalog)Rovenue reads it with the connection's rvwh_ secret every 15 minutes while the Campaigns page is open, and on Refresh catalog

When you save the connection, Rovenue asks Advenue to register the webhook for you and stores the signing secret Advenue returns, encrypted. The Campaigns page shows Attribution webhook registered automatically. Deleting the connection removes the webhook and the connection's catalog campaigns; recorded attributions and your mappings stay.

Set $advenueId before the first onboarding

Rovenue finds the subscriber an attribution belongs to by the $advenueId attribute, so set it as shown in Identity and await it before you present the onboarding placement. If Advenue's attribution arrives before $advenueId is set, Rovenue keeps it for up to 72 hours and applies it the moment the attribute is written. If the first placement is fetched before Advenue has attributed the install, that first onboarding is the default one; later placements see the attribution.

Optionally, call Advenue.setUserId(Rovenue.rovenueId) as well. Advenue then sends the Rovenue id with the attribution, and Rovenue matches on it first.

How Advenue's data is read

  • A campaign's network is the network of the Advenue link it came from, the same for the catalog and for every install from that link, whether the click was paid or not: a TikTok link is TikTok, a Facebook or Instagram link is Meta. The networks' own claims (Meta, Google Ads, Apple Search Ads) map the same way, so a Meta campaign mapped once matches Meta installs from every source. Links with no ad network (owned links, influencer links, QR codes) are listed under Other, split by campaign.
  • A campaign's id is the network's own campaign id when Advenue has one, and otherwise the id of the Advenue campaign the link belongs to. Before any traffic, a Meta (or other ad-network) link's campaign is listed under the Advenue campaign id, because only the clicks carry Meta's campaign id. As soon as Advenue reports an install that names both, the two become one row under Meta's id. Map the campaign on its catalog row before launch: that mapping matches the first install Advenue reports and, from then on, Meta installs Rovenue's own Meta install referrer records for the same Meta campaign. A link that sends traffic to several Meta campaigns (through the campaign_id macro) keeps its Advenue row, and a mapping on it matches all of them.
  • Probabilistic matches are accepted like deterministic ones. Installs Advenue flags as fraud, and re-attributions, are ignored.
  • Installs of a subscriber seen only through a Sandbox key count in the Sandbox list.

What the catalog lists

Catalog campaigns show From Advenue and 0 installs until installs arrive. They are never flagged NEW. The catalog has three origins:

  • link: every campaign of your Advenue tracking links, once per link network.
  • spend: campaigns of your ad-spend connections in the last 90 days.
  • observed: campaigns Advenue attributed installs to in the last 90 days, with their ad sets and ads.

Advenue cannot list a network campaign it has never seen: one with no cost connection and no install yet appears only after its first install.

Manual webhook setup

If your Advenue cannot register the webhook itself, the Campaigns page shows Attribution webhook: set it up in Advenue with your project's Advenue webhook URL (also under Acquisition › Settings). In Advenue, add a project webhook for the install.attributed event with that URL, then paste its signing secret (whsec_…) into the connection's Attribution signing secret field. Use Advenue's Send test: the Campaigns page then shows the webhook as verified.

Rotate the postback URLs in Acquisition settings also issues a new Advenue URL; Rovenue re-registers it with Advenue for each connection. The previous Advenue URL keeps working until Advenue has confirmed the new one (Rovenue retries if Advenue is down), and for at most 72 hours, so no install is lost in between; the Campaigns page shows when a confirmation is still pending. On the manual path, update the URL in Advenue yourself within those 72 hours.

Troubleshooting

SymptomCause and fix
Advenue's delivery log shows 401 ADVENUE_SIGNATURE_INVALIDThe signing secret on the connection is not the webhook's, or the delivery is older than 5 minutes. Save the connection again (automatic path) or paste the current whsec_… (manual path), then redrive the delivery in Advenue.
404The URL's token was rotated or belongs to another project. Copy the current URL.
202 pendingNo subscriber has that $advenueId yet. The attribution is applied when the app sets it (within 72 hours).
Catalog: "secret rejected"The connection's rvwh_ secret was revoked in Advenue. Paste a new one.
Catalog: "this Advenue does not serve the campaign catalog yet"Your Advenue release has no catalog. Campaigns appear once installs arrive.
Catalog: "Advenue unreachable or timed out"Advenue was down; the last catalog stays listed and the next refresh retries.
"Advenue listed only part of its catalog"More than 5,000 campaigns: nothing was removed, but some may be missing.
An Advenue campaign shows merged into the wrong Meta campaignAdvenue reported an install or catalog entry naming both ids, so Rovenue treats them as one campaign, and it never forgets that on its own. First fix the link or its campaign_id macro in Advenue, so the pair is not reported again. Then, on a self-hosted install, delete the pair: DELETE FROM acquisition_campaign_aliases WHERE "projectId" = '<project id>' AND network = 'meta' AND "advenueCampaignId" = '<Advenue campaign id>' AND "campaignId" = '<wrong Meta campaign id>';. On Rovenue Cloud, ask support. Mappings are not changed by this; check the Campaigns page afterwards.

On this page