Your attribution dashboard answers the marketing question: which campaign drove this install. Your warehouse, CRM, and internal services need the same answer the moment it lands, not at the next export. That is what attribution webhooks are for.
This is a practical setup guide. It covers what an attribution webhook is, which events are worth streaming, what the payload looks like, how to handle retries and verification, and where teams usually route the data. It assumes you want events flowing to systems you control, not just charts you read.
An attribution webhook is a real-time HTTP POST that your MMP sends to a URL you own the instant an attributed event happens, delivering the full event payload so your own systems can act on it without polling an API or waiting for a batch export.
Step 1: Decide which events to stream
Start from the jobs, not the event catalog. The events worth wiring almost always map to a downstream action:
- Install / attributed install sends a new acquisition into your warehouse and lifecycle tools with its source attached.
- Onboarding event (the activation step you define, such as signup or first purchase) triggers welcome flows and marks a real activation, not just a download.
- Purchase / revenue event ties revenue to the campaign that drove it, which is what finance and ROAS reporting need.
- Postback / re-engagement event keeps remarketing and reward logic in sync.
Pick the smallest set that powers a real workflow. You can add more later. If you are unsure whether a webhook or a postback is the right channel for a given event, read webhooks vs postbacks vs server-to-server first.
Step 2: Stand up an endpoint
Your endpoint is any HTTPS URL that accepts a POST and returns quickly. The rules that keep it reliable:
- Return 2xx fast. Acknowledge receipt, then process asynchronously. Do not run a slow database write before responding, or you will trigger retries.
- Be idempotent. Use the event id as a dedupe key so a retried delivery does not double-count a purchase.
- Accept JSON. Most MMP webhooks post a JSON body.
A minimal handler looks like this:
// POST /webhooks/linkrunner
app.post("/webhooks/linkrunner", async (req, res) => {
// 1. Acknowledge immediately
res.status(200).send("ok");
// 2. Dedupe on event id, then process out of band
const event = req.body;
await queue.enqueue(event.event_id, event);
});
Step 3: Know your payload
A webhook is only useful if you know the shape of what arrives. An attributed install payload typically carries the event type, a unique id, a timestamp, the attribution source, and device or user context. A representative shape:
{
"event_id": "evt_01HZX...",
"event_name": "install",
"timestamp": "2026-06-04T09:21:44Z",
"attribution": {
"source": "meta",
"campaign": "summer_uac",
"ad_set": "lookalike_2pct",
"deep_link": "myapp://product/123"
},
"device": {
"platform": "android",
"app_version": "4.2.0"
},
"user": {
"customer_id": "u_8842",
"is_organic": false
}
}
Map the fields you need into your schema once, and every later event flows through the same transform. Check your MMP's docs for the exact field names. Linkrunner's payloads are documented in the developer docs.
Step 4: Handle retries and ordering
Networks fail. A good webhook setup assumes that and stays correct anyway:
- Retries: if your endpoint does not return 2xx, the sender retries with backoff. That is why idempotency on
event_idis non-negotiable. - Ordering: do not assume events arrive in order. A purchase webhook can land before the install webhook it depends on. Reconcile on ids and timestamps rather than arrival order.
- Replay: keep the raw payloads for a few days so you can replay into a new consumer without re-triggering events upstream.
Step 5: Verify authenticity
Treat the endpoint as public and verify every delivery:
- Signature header: verify the HMAC signature your MMP sends against your shared secret before trusting the body.
- Allowlist: optionally restrict to known sender IPs.
- HTTPS only: never accept event data over plain HTTP.
import crypto from "crypto";
function isValid(rawBody, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(rawBody)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature),
);
}
Step 6: Route the data where it does work
Once events arrive verified, fan them out:
- Warehouse (BigQuery, Snowflake, Redshift) for attributed installs next to revenue.
- CDP or CRM (Segment, Braze, CleverTap) to trigger lifecycle journeys keyed off the attribution source.
- Slack or alerting for spikes, drops, and qualified-install pings.
- Internal services for fraud checks, reward payouts, and reconciliation.
This is also where webhook availability on your plan matters. If real-time delivery is gated behind a higher tier, these integrations wait. For why we include webhooks on every plan, see Branch webhooks: what they cost and the free alternative, and check the per-plan view on the pricing page.
FAQ
Q: Which events can I send to a webhook?
Any attributed event your MMP tracks: installs, your defined onboarding or activation event, purchases and revenue events, re-engagements, and postback events. With Linkrunner you choose the events you want streamed.
Q: Is there a webhook limit or per-event fee?
On Linkrunner, no. Webhook delivery is included on every plan with no separate allowance to buy. Some MMPs meter real-time delivery or gate it to higher tiers, so check the plan you are on.
Q: Do webhooks work in real time?
Yes. A webhook fires as the event is processed, so your systems see it within seconds rather than waiting for a scheduled export.
Q: What happens if my endpoint is down?
The sender retries with backoff. Because deliveries can repeat, make your handler idempotent by deduping on the event id so a retry never double-counts.
Q: Do all Linkrunner plans include webhooks?
Yes, including the free tier. You can wire and test the full pipeline before you pay for any attributed installs.
Closing
The setup is the same on every reliable MMP: pick the events that drive a workflow, stand up a fast idempotent endpoint, verify signatures, handle retries, and route the data to the systems that act on it. The only variable that should not slow you down is whether your plan lets you stream events at all.
If you want to wire this today on a free plan, start with Linkrunner or read the webhook docs for the exact payloads and signatures.
