impUrl— fired when the ad becomes visible (impression pixel)clickUrl— navigated to when the user clicks the ad
api.trygravity.ai. A tracking proxy lets you route them through your own domain instead, so you can log every impression and click on your own server before forwarding to Gravity.
This is the same pass-through pattern advertisers use for first-party conversion tracking — applied to the publisher side.
Why proxy tracking?
- First-party data — impressions and clicks hit your domain, so you can log them in your own analytics, data warehouse, or billing system.
- Verification — independently verify the impression and click counts Gravity reports.
- Latency visibility — monitor tracking endpoint performance from your own infrastructure.
- No SDK changes required — the SDK fires whatever URL is on
impUrl/clickUrl. You just rewrite them on your server before passing the ad to your client.
How it works
1
Set up a reverse proxy
Add a route on your server (e.g.
/gravity/) that forwards requests to api.trygravity.ai.2
Rewrite tracking URLs
On your server, after calling
gravity.getAds(), replace the Gravity domain in impUrl and clickUrl with your own proxy domain.3
Log on your side
Your proxy receives every impression and click request. Log whatever you need, then forward to Gravity.
1. Set up the reverse proxy
Nginx
Next.js (middleware or API route)
Express
Python (FastAPI)
2. Rewrite tracking URLs
After callinggravity.getAds() on your server, replace the Gravity domain in the ad response with your proxy path before sending to the client.
Node / TypeScript
Python
The encrypted
?p= token in each URL is opaque and tamper-proof. You’re only changing the domain prefix, so all billing and attribution still works exactly as before on Gravity’s side.3. Log impressions and clicks
Your proxy server receives every tracking request. Here’s what each path tells you:
The
?p= query parameter is an encrypted payload containing the click ID, campaign ID, publisher ID, ad ID, and price. You can’t decrypt it (it’s encrypted with Gravity’s key), but you can count requests, log timestamps, and correlate with your own session/user data from request headers.
Example: structured logging
Alternative: client-side callbacks
If you don’t need a full proxy, the React SDK hasonImpression and onClick callbacks that fire client-side:
Important notes
- Always forward
X-Forwarded-For— Gravity uses the end user’s IP for geo-targeting and fraud detection. Without it, all impressions appear to come from your server’s IP. - Forward
User-Agent— used for device-type classification and bot filtering. - Don’t cache — every impression and click request must reach Gravity. Impressions are deduplicated server-side, but a cached response would silently drop billing events.
- Click redirects — the
/track/clickendpoint returns a302redirect to the advertiser’s landing page. Make sure your proxy passes through the redirect response (don’t follow it server-side).
Show ads
How impression and click tracking works in the SDK.
Payouts
How your tracked impressions translate to revenue.

