RevnuDocs
Browse the Docs▾

Measurement / Send Events

Send Events

POST/api/measurement/events

Tell Revnu from your server when a visitor signs up, books a call or pays, so the result is tied back to where they came from.

Last updated

The Revnu Tag sees visits. The Event API is how your server tells Revnu something real happened: a signup, a booked call, a payment. Revnu joins the event to the visit that led to it, so you can see which source (an AI assistant, search, an ad) brought the customers who converted.

curl https://revnu.com/api/measurement/events \
  -H "Authorization: Bearer $REVNU_EVENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "event_id": "signup_8412",
    "event_name": "signup",
    "anonymous_id": "ra_3f9c0a1b2c3d4e5f60718293a4b5c6d7",
    "consent_state": "granted",
    "email": "ana@example.com"
  }'

Your event key

The event key starts with rsk_live_ and comes with your site key. Keep it in a server-side environment variable: anyone who has it can send events for your site. It is not the rvp_ personal API token.

Connect the visit to the event

The tag gives every visitor an id. Read it in the browser and send it to your backend with the signup, booking or checkout:

const anonymousId = window.revnu?.anonymousId; // "ra_..."

Then pass it as anonymous_id when your server sends the event. That id is what ties the event to the visit.

Save the visitor's consent choice at the same moment, and send it as consent_state:

const consentState = window.revnu?.getContext().consentState; // "granted", "pending" or "denied"

Revnu sends every event to your ad platforms unless consent_state is denied, so an event without it still counts for your ads. Sending the saved choice is what keeps a visitor who declined out of them.

Request

Field Required Notes
event_id yes Your stable id for this event. 1-128 letters, digits, ., _, : or -. Sending the same id again is safe: it is reported as a duplicate, not counted twice.
event_name yes Lowercase snake_case, for example signup, demo_booked, purchase.
occurred_at no ISO 8601 date or milliseconds. Defaults to when Revnu receives it.
anonymous_id no window.revnu.anonymousId from the visit.
consent_state no granted, denied or pending: the visitor's choice saved with the signup, booking or checkout. Every event except denied is sent to your ad platforms.
google_ad_user_data, google_ad_personalization no granted, denied or unknown. Google Ads receives every event except one where google_ad_user_data is denied.
gclid, gbraid, wbraid, fbclid, ttclid, _ttp, twclid, li_fat_id, msclkid, rdt_cid no Ad click ids or Pixel cookies you stored yourself. Only needed when the visit cannot be joined by anonymous_id, for example when the tag was blocked.
email, phone, external_user_id no Normalized and hashed for matching.
amount, currency no Send both, for example 49 and "USD".
properties no An object of extra facts, for example { "plan": "pro" }.
reversal_of no The event_id of an earlier event this one cancels, such as a refund. Repeat the original amount and currency.

Node.js

await fetch("https://revnu.com/api/measurement/events", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.REVNU_EVENT_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    event_id: `signup_${user.id}`,
    event_name: "signup",
    occurred_at: user.createdAt.toISOString(),
    anonymous_id: revnuAnonymousId, // sent up from the browser
    consent_state: savedConsentState, // getContext().consentState, saved at signup
    email: user.email,
  }),
});

Response

{
  "accepted": true,
  "matched": false,
  "counted": false,
  "not_counted_reason": "\"signup\" is not in this site's win definition, which counts \"trial_started\". It was recorded, but it will not count as a win until the definition in Revnu includes it.",
  "duplicate": false,
  "enriched": false,
  "event_id": "signup_8412",
  "event_name": "signup",
  "roles": [],
  "attribution_status": "pending"
}
  • counted says whether the event counts as a win under your site's win definition.

  • not_counted_reason appears when an event can never count because the definition does not include its event_name. Change the definition in Revnu, or send the event it names.

  • matched says whether the event was credited to one of your Revnu ad campaigns. It stays false until you run campaigns through Revnu, and that is expected.

Code Meaning
200 Recorded and credited to one of your Revnu ad campaigns, or a duplicate of an event already recorded
202 Recorded, not credited to a campaign. Check counted to see whether it counts as a win
401 Missing or invalid event key
409 The same event_id was sent before with different values
413 Body over 64 KB
422 A field failed validation; error says which
429 Rate limited; retry later with the same event_id

Agents: this page is also markdown at /docs/event-api.md, answers Accept: text/markdown, and is listed in /docs/llms.txt.

Frequently Asked Questions

No. The event key would be public. Send events from your backend, a serverless function or a webhook handler, and let the browser pass along only the `anonymous_id`.