Back to all articles

How to connect Elo to Amplitude for ad engagement analytics

Connect Elo ad events to Amplitude in 2026: build the event bridge, avoid double-counted impressions, and choose real-time vs batch sync.

ELContent TeamSep 16, 2026 — 8 min read
How to connect Elo to Amplitude for ad engagement analytics

Elo tells you which ads ran and what they earned. Amplitude tells you what the user did next. Connect the two and you get a single timeline: ad shown, ad clicked, session continued or churned — instead of manually cross-referencing Elo's revenue log against a separate analytics export, set up an event bridge so every Elo ad event lands in Amplitude with your existing user and session properties attached.

This guide covers the standard path: forwarding Elo ad events (impression, click, conversion) into Amplitude's HTTP API so they show up next to your product events in 2026. It also covers the batch alternative for teams that don't want a live webhook running.

TL;DR
  • Elo ad events (impression, click, conversion) can be forwarded to Amplitude's HTTP API v2 as custom events tied to your existing user_id.
  • A small serverless function is the cleanest bridge — no SDK changes needed on either side.
  • Amplitude dedupes on insert_id, so skipping a stable ID causes double-counted ad revenue in your dashboards.
  • Batch sync via a nightly job is the fallback when a live webhook isn't practical for your stack.
  • Elo amplitude ad analytics integration takes one bridge script and one Amplitude project — no vendor lock-in on either side.

Why this matters

Ad revenue and product engagement live in different systems by default. Elo's dashboard tells you CPM, fill rate, and revenue by placement. Amplitude tells you retention, session length, and funnel drop-off. Neither one alone answers "do users who see ads churn faster than users who don't" — that answer only exists once both event streams share a user ID and a timeline.

Teams running ad-supported AI chat apps in 2026 need this join more than typical publishers do: ad load, ad relevance, and session continuation are tightly coupled in a conversational interface in a way they aren't on a static page. A bad ad match doesn't just fail to convert — it can end the conversation. Amplitude is where you'd catch that pattern; Elo is where the event originates.

Before you start

  • Elo SDK already live in your app and serving ads — this integration forwards events, it doesn't set up ad serving.
  • An Amplitude project with a Project API Key and Secret Key (Amplitude Settings > Projects > your project > General).
  • A place to run the bridge — a serverless function (Vercel, AWS Lambda, Cloudflare Workers) or a small backend endpoint that can receive Elo events and forward them.
  • The gotcha: Amplitude dedupes events using an insert_id field. If your bridge retries a failed send without reusing the same insert_id, the same ad impression gets counted twice in Amplitude — inflating your engagement metrics without any change in actual ad volume. Generate the insert_id from the Elo event's own unique ID, not a timestamp, before you write a single line of forwarding code.

Set up the event bridge

Capture Elo ad events

  1. In your app's ad-handling code, locate where Elo events fire — impression, click, and conversion each carry an event type, a placement or ad slot identifier, and a timestamp.
  2. Attach your app's existing user identifier to each event before it leaves your server. This is the field Amplitude will join on, so it has to match the user_id you already send from your product events.
  3. Send each captured event to your bridge endpoint (the serverless function from the prerequisites) rather than directly to Amplitude — this keeps your Amplitude keys off the client.

Expected result: your bridge endpoint receives a payload for every impression, click, and conversion, tagged with a user ID it can reuse.

Configure the Amplitude HTTP API call

  1. In the bridge function, build a request to Amplitude's HTTP API v2 endpoint (https://api2.amplitude.com/2/httpapi).
  2. Set event_type to something specific per event — Elo Ad Impression, Elo Ad Click, Elo Ad Conversion — so they're filterable in Amplitude without extra properties.
  3. Populate event_properties with the ad slot, the placement, and (if available) the advertiser category — this is what lets you later filter retention by ad type, not just "saw an ad, yes/no."
  4. Set insert_id to the Elo event's native event ID. This is the dedup key from the gotcha above — get it right here and you never think about it again.
  5. Send the request with your Amplitude API Key in the payload. A 200 response confirms Amplitude accepted the event; a 429 means you've hit rate limits and need to queue or batch instead of firing one request per event.

Expected result: a test impression fired from your app appears in Amplitude's live event stream (Amplitude > User Lookup or Event Explorer) within seconds, carrying the Elo Ad Impression event type and your placement property.

Verify the join works

  1. In Amplitude, build a simple segmentation chart: Elo Ad Impression as the event, split by placement.
  2. Cross-reference the count against Elo's own event log for the same time window — they should match, not just be close.
  3. If Amplitude's count is higher than Elo's, that's the double-count gotcha from above — check your insert_id logic first.

Batch sync instead of real time

A live webhook isn't the only path, and for lower-traffic apps it's often more work than it's worth. Instead of forwarding events as they fire, pull Elo's event log on a schedule and push it to Amplitude in bulk:

  1. Set up a scheduled job (cron, GitHub Actions, or your platform's scheduler) that runs once a day or once an hour depending on how fresh you need the data.
  2. Pull the prior period's Elo events in one request rather than event-by-event.
  3. Transform each Elo event into the same Amplitude event shape described above — same event_type naming, same insert_id rule.
  4. Send the batch to Amplitude's HTTP API in a single call (Amplitude accepts arrays of events in one request), which is also easier on your rate limits than firing individual requests all day.

Batch sync is the right call when you don't need same-day ad-engagement dashboards; real-time forwarding is the right call when you're actively tuning ad placement or frequency caps and need to see the effect within the hour.

ApproachSetup effortData freshnessBest for
Real-time webhookHigher — needs a live endpointSecondsTeams actively testing placement or frequency changes
Nightly/hourly batchLower — a scheduled scriptHours to a dayTeams that just need ad engagement in weekly reporting

Troubleshooting

  • Events show up in Elo but never reach Amplitude. Check your bridge function's logs for a non-200 response first — a malformed event_properties object (nested objects Amplitude doesn't accept) is the most common cause.
  • Amplitude shows roughly double the impression count Elo logs. This is the insert_id dedup issue — you're likely generating a new ID on retry instead of reusing the original event's ID.
  • Events arrive in Amplitude with no user_id. The Elo event fired before your app attached the user identifier, usually on the very first ad shown in a session before login state resolves. Delay the forward until the user ID is available, or drop pre-identification events from the sync.
  • 429 responses under load. You're sending one HTTP request per event during a traffic spike. Switch to the batch endpoint pattern from the section above, even if you keep the rest of the pipeline real-time.
  • Amplitude event counts match, but properties are missing. Confirm the property names in your bridge match exactly what you're filtering on in Amplitude charts — a silent typo in event_properties doesn't error, it just shows up as an empty segment.

Customize your workflow

Once impressions, clicks, and conversions are landing cleanly in Amplitude, the next move is deciding what to build on top of it. A few directions worth taking:

  • Segment retention curves by whether a session included an ad, and by which placement, to see if ad load is costing you retained users.
  • Feed the same event stream into a broader ad revenue reporting dashboard so revenue and engagement sit on one screen instead of two.
  • Once user-level join is working, use it to measure ad revenue per user instead of just aggregate CPM across your app.

Add ad revenue events to your stack

Elo's SDK is what generates the events this guide forwards to Amplitude.

FAQ

What is the elo amplitude ad analytics integration used for?

It forwards Elo's ad events — impression, click, conversion — into Amplitude so ad engagement sits next to product usage data in the same dashboard. Without it, ad performance and retention live in two disconnected systems.

Do I need to change my Elo SDK installation to send events to Amplitude?

No. The SDK keeps serving ads exactly as configured; a separate bridge (a serverless function or backend endpoint) captures the events Elo already fires and forwards them to Amplitude's API.

Why does Amplitude show more ad impressions than Elo's own log?

This is almost always a missing or unstable insert_id on retried events. Amplitude dedupes by insert_id, so reusing the same ID from the original Elo event prevents the same impression from counting twice.

Should I sync ad events to Amplitude in real time or in a batch job?

Real-time forwarding suits teams actively adjusting ad placement or frequency caps and watching the effect same-day. A nightly or hourly batch job is enough for teams that only need ad engagement in weekly reporting.

Can I filter Amplitude retention charts by ad placement?

Yes, as long as your event_properties include the placement or ad slot identifier when the event is forwarded from Elo. Without that property attached at send time, you can't filter by it later.

What causes a 429 error when sending Elo events to Amplitude?

A 429 means you're hitting Amplitude's rate limit, usually from sending one HTTP request per individual event during a traffic spike. Switching to Amplitude's batch endpoint for the same event volume resolves it.

Does this integration replace Elo's own revenue dashboard?

No. Elo's dashboard remains the source of truth for CPM, fill rate, and payout data; Amplitude becomes the place to see how ad exposure correlates with retention and session behavior.

One last thing

The part teams skip and regret is the insert_id field — it looks optional in testing because a handful of duplicate events don't move any chart. At scale in 2026, with thousands of daily ad impressions across an active chatbot, an unstable dedup key quietly inflates every ad-engagement metric in Amplitude until someone notices the numbers don't reconcile with Elo's own log. Set it once, correctly, before the first real event ships.

You might also like