Docs

Conversion definitions

A definition says what counts and how each platform calls it. Conversions without a definition are possible (manual entries), but only definitions map to platform events.

PUT /v1/projects/{project}/conversion-definitions/{key} (scope project:admin) creates or replaces one (scopes conversions:write + config:write); GET …/conversion-definitions lists them; MCP conversions_definitions_list reads them.

{
  "name": "Demo booked",
  "trigger": { "kind": "event", "event": "booking" },
  "source": "booking",
  "value": 500,
  "currency": "EUR",
  "providers": {
    "meta": { "enabled": true, "eventName": "Schedule" },
    "linkedin": { "enabled": true, "conversionRule": "12345678" },
    "google_ads": { "enabled": true, "conversionAction": "customers/1234567890/conversionActions/987654321", "feedName": "Demo booked (Server)" },
    "tiktok": { "enabled": true, "event": "Contact" }
  },
  "enabled": true,
  "requireServerConfirmation": false
}

Triggers

trigger.kindCreated whenEvent idOrigin
manualonly explicitly: REST POST …/conversions, server SDK, MCP conversions_mark, dashboard – never from the browseryours (or generated)server / mcp / dashboard
beaconthe browser conversion beacon POST /v1/cb (x3.conversion(), reportBooking()) – and explicitly like manual. The beacon is refused (404) for every other kindthe page's (shared with the pixel)web
event (+ optional props that must match)the browser or server sends that event<pageview id>:<n>web
goala session reaches the goal for the first timegoal:<session>:<key>web
lead (+ optional form)a lead is created by identify() or POST …/leadslead:<lead id>web / server

Automatic event ids are deterministic, so a retried batch never creates a second conversion.

Source

source is stored on every row and is a filter in reports. Values: quiz, booking, whatsapp_manual, manual, event, goal, lead, api. The CPI preset uses quiz, booking and whatsapp_manual so historical reports stay comparable.

Platform mapping

PlatformFieldWhere to find it
MetaeventName – a standard event (Lead, Schedule, Contact, CompleteRegistration, Purchase, …) or a custom nameuse the same name as your browser pixel for deduplication
LinkedInconversionRule – numeric id or urn:lla:llaPartnerConversion:<id>Campaign Manager → Conversion tracking → rule details
Google AdsconversionAction (API) and/or feedName (CSV feed: the action's exact name)Goals → Conversions → action (ctId in the URL)
TikTokevent – SubmitForm, Contact, CompleteRegistration, Lead …Events Manager of the pixel

A platform without mapping, or with enabled: false, gets status not_configured for this definition – no error.

Requiring server confirmation

Public-key traffic can be forged. For definitions whose uploads influence bidding, set requireServerConfirmation: true: web-triggered rows are stored as held and dispatched only when your server confirms them – either conversions.create with the **same eventId** or PATCH …/conversions/{id}/status {"status":"pending"}. Held rows expire after 7 days (skipped).

Independent of this flag, web-originated conversions always pass the abuse guards: the session must exist with at least one pageview and engagement, it must not be test traffic, at most one conversion per session and definition, and at most settings.conversions.webDailyCap (default 500) per project and day.

Typical setups

SiteDefinitionTrigger
Lead-gen with a quizquiz_leadlead with form: "quiz" (your server calls leads.create with conversion)
Calendar bookingdemo_bookedevent booking (SDK booking plugin) or the /v1/cb beacon
WhatsApp / phonewhatsapp_contactmanual – confirmed via MCP conversions_mark with a time window
Newsletternewslettergoal newsletter_signup
Form via SDK forms plugincontact_formevent form_submit with props: {"form": "contact"}