Conversions & goals
Track revenue-generating actions and attribute them to the right traffic source.
How conversions are tracked today
Conversions are currently tracked through the standard Events API using event_type=conversion. There is no separate /v1/projects/{site_id}/conversions endpoint; the examples below all post to POST /v1/projects/{site_id}/events. A dedicated conversions endpoint is planned for a later release.
Conversion vs. event
A conversion is just a special kind of event with two extra semantics:
- It carries optional
revenueandcurrencyfields. - The Goals UI (beta) is available in the console — events are matched against goals you define so the Conversions dashboard shows conversion rates and revenue per source automatically.
Track a conversion from the browser
window.oa('conversion', 'purchase', {
revenue: 49.99,
currency: 'USD',
plan: 'pro'
});
Browser conversions are useful for "thanks" pages and lead forms, but they can be blocked by ad-blockers. For revenue, always also send a server-side conversion — it's the source of truth.
Track a conversion from the backend
From your payment webhook handler, send the same conversion through the REST API. See the Server-side guide for PHP and Node examples.
curl -X POST https://api.openanalyticsapi.com/v1/projects/SITE_ID/events \
-H "Authorization: Bearer oa_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"event_type": "conversion",
"event_name": "purchase",
"user_id": "sha256_user_hash",
"revenue": 49.99,
"currency": "USD",
"properties": {"plan":"pro","order_id":"ord_123"}
}'
Include a unique business ID (like order_id) in properties so you can dedupe in queries if your webhook retries. A server-side Idempotency-Key header is on the roadmap but not yet implemented.
Goals Beta
The Goals and Conversions beta UI is available in the console. Under Goals you define what counts as a conversion — match by event name, event type, URL path, or any event_type = conversion event — and the Conversions dashboard shows counts, revenue, conversion rate, and a per-source/per-event breakdown. Matching runs at query time against your existing event data, so goals you define now also apply retroactively.
Send conversion events with a consistent event_name (e.g. purchase, signup) and an order_id property. A Funnels beta UI is also available in the console — build a multi-step funnel and see step-by-step drop-off. Retention/cohorts and multi-touch attribution remain in development and are not part of this beta.
Attribution
The tracker captures UTM parameters and the referrer on the first pageview of each session and stores them with every subsequent event in that session. From there, attribution is computed at query time from the captured data:
- Last-touch (default) — credit the most recent known source before the conversion. This is what today's Sources dashboard surfaces.
- First-touch — credit the first known source for the user. Computed from the same captured data; dedicated attribution endpoint on the roadmap.
- Multi-touch (linear) — split credit equally across all sources. On the roadmap.
The lookback window defaults to 30 days. The raw UTM + referrer data is durable in event storage, so models added later can be retro-applied to historical events.
Conversion forwarding to ad platforms
Every conversion recorded for a project can be forwarded server-side, which recovers the conversions that ad blockers and iOS ATT strip out of browser pixels. Configure it in the console under Conversion forwarding.
Two destination types are available today:
- Meta Conversions API — enter your Pixel ID and access token. Optionally set a test event code while you verify the setup, so events land in Meta's Test Events tab instead of your live data.
- Webhook — we POST the conversion as JSON to an https endpoint you control, signed with HMAC-SHA256 in the
X-OA-Signatureheader so you can verify it came from us. Use this to reach any platform we don't support natively.
What leaves our server: event name, timestamp, page URL, value and currency. Email addresses are always SHA-256 hashed first — the plaintext never leaves. We do not send IP addresses at all; we only ever store them anonymized, so they would be useless for attribution anyway.
Failed forwards are retried three times with backoff. If they still fail, the error is shown on the destination in the console — conversions are never dropped silently.
Google Enhanced Conversions is not supported yet and is on the roadmap.