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
- 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. - In the Rovenue dashboard, open Integrations, pick Advenue and paste the secret.
- 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/rovenueitself and refuses an endpoint that carries a query string or fragment, or that points at a private address. - 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 event | Advenue event | Revenue |
|---|---|---|
subscription.trial.started | subscription_started | 0 |
revenue.INITIAL | subscription_converted (subscription) or iap_purchase (other products) | +amount |
revenue.TRIAL_CONVERSION | subscription_converted | +amount |
revenue.RENEWAL | subscription_renewed | +amount |
revenue.REACTIVATION | subscription_renewed | +amount |
revenue.NON_RENEWING_PURCHASE | iap_purchase | +amount |
revenue.CREDIT_PURCHASE | iap_purchase | +amount |
revenue.REFUND | subscription_churned (subscription) or iap_purchase (other products) | −amount |
subscription.expired | subscription_churned | none |
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:
| Reason | Meaning |
|---|---|
no_mapping | The 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_scope | The 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_data | The subscriber has no $advenueId and no authorized IDFA, or was erased before the delivery. Set $advenueId as above. |
invalid_revenue | A 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
| Direction | What | How |
|---|---|---|
| Rovenue → Advenue | Store-verified revenue and subscription events | Events sent |
| Advenue → Rovenue | One attribution per install Advenue attributes: network, campaign, ad set, ad | The install.attributed webhook, posted to your project's Advenue URL and signed by Advenue |
| Rovenue ← Advenue | The 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_idmacro) 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
| Symptom | Cause and fix |
|---|---|
Advenue's delivery log shows 401 ADVENUE_SIGNATURE_INVALID | The 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. |
404 | The URL's token was rotated or belongs to another project. Copy the current URL. |
202 pending | No 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 campaign | Advenue 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. |
Using Rovenue with AI & LLMs
Machine-readable docs endpoints, copy-paste context primers, and tips for integrating Rovenue with coding assistants and AI agents.
Meta Conversions API (CAPI)
Forward Rovenue subscription and revenue events to Meta's server-side Conversions API for reliable attribution without client-side pixels.