Choosing your events
The full Lapis conversion event catalog, data shapes, and how to choose the right events for your business.
Lapis uses the same conversion event taxonomy as the OpenAI Ads platform, so a single integration produces consistent numbers in both systems. This page is the full catalog. The guides in this section show exactly which events to implement for your business model, with working code.
Pick your integration guide
| Your business | Guide | Primary events |
|---|---|---|
| Online store (Shopify, WooCommerce, custom checkout) | Ecommerce and Shopify | order_created, checkout_started, items_added |
| SaaS, self-serve signup, product-led growth | SaaS and signups | registration_completed, trial_started, subscription_created |
| Lead gen, demos, consultations, bookings | Lead gen and bookings | lead_created, appointment_scheduled |
| Mobile app installs | Mobile apps | app_installed, app_opened |
Most businesses need two or three events, not all thirteen. Implement your primary conversion first (the thing your ads are optimized for), verify it end to end, then layer in funnel events.
The full event catalog
| Event | Data shape | When to send it |
|---|---|---|
page_viewed |
contents |
A page loads. The Lapis browser pixel sends this for you, so you rarely send it yourself. |
contents_viewed |
contents |
A specific product, article, listing, or plan is viewed, including interactions after page load. |
items_added |
contents |
An item goes into a cart, bundle, comparison, or selection flow. |
checkout_started |
contents |
Checkout begins. |
order_created |
contents |
A purchase completes. This is the core ecommerce conversion. |
lead_created |
customer_action |
A lead form is submitted, or a contact or inquiry request is made. |
appointment_scheduled |
customer_action |
A demo, meeting, consultation, or appointment is booked. |
registration_completed |
customer_action |
An account, webinar, event, or product registration completes. |
trial_started |
plan_enrollment |
A free trial starts. |
subscription_created |
plan_enrollment |
A paid subscription starts. |
app_installed |
customer_action |
A mobile app is installed. Conversions API only. |
app_opened |
customer_action |
A mobile app is opened. Conversions API only. |
custom |
custom |
A conversion that genuinely fits no standard name. Prefer standard events. |
Data shapes
Every event’s data object has a type field that names its shape. Money is always an integer in the currency’s minor unit (12999 means $129.99), and it always carries an ISO 4217 currency whenever an amount is present.
contents
Use for commerce-flavored events: order_created, checkout_started, items_added, contents_viewed, page_viewed.
| Field | Required | Notes |
|---|---|---|
type |
Yes | Must be "contents". |
amount |
No | Event-level value in minor units. |
currency |
With amount |
ISO 4217, for example USD. |
contents |
No | Array of item records (see below). |
customer_action
Use for people-doing-things events: lead_created, appointment_scheduled, registration_completed, app_installed, app_opened.
| Field | Required | Notes |
|---|---|---|
type |
Yes | Must be "customer_action". |
amount |
No | Optional value in minor units (for example, estimated lead value). |
currency |
With amount |
ISO 4217. |
plan_enrollment
Use for subscription-lifecycle events: trial_started, subscription_created.
| Field | Required | Notes |
|---|---|---|
type |
Yes | Must be "plan_enrollment". |
plan_id |
No | Your internal plan identifier, for example pro_monthly. |
amount |
No | Plan value in minor units. |
currency |
With amount |
ISO 4217. |
contents |
No | Optional plan-related item records. |
Content item fields
When you send contents: [...], each item may include:
| Field | Type | Notes |
|---|---|---|
id |
string | Your internal item ID (SKU, plan ID). |
name |
string | Human-readable label. |
content_type |
string | product, plan, article, page, and so on. |
quantity |
integer | Never a string. |
amount |
integer | Item-level value in minor units. |
currency |
string | Include with an item-level amount unless the event-level currency already covers it. |
Rules that apply to every event
- Use a stable, unique
idper conversion. Derive it from your own primary key:order_created:4211,registration_completed:acct_8f2. Retries must reuse the sameid, because Lapis and OpenAI both deduplicate on it. - Send confirmed conversions only. Fire from the backend after the order is paid or the account exists, not from an optimistic frontend callback.
- Send one revenue-bearing event per business conversion. Do not send both
order_createdand a custompurchase_completedfor the same order. - Include
lapis_click_idwhenever you have it. Events without one are accepted as unattributed (HTTP 202) rather than misattributed. - Follow the naming rules for custom events: 1 to 64 characters, lowercase letters, numbers, underscores, and hyphens only, and never reuse a standard name.
Note: If you already send server events to OpenAI’s Conversions API, the Lapis payload is intentionally compatible. Duplicate the call, add
lapis_click_id, and you are done. See the Conversion API reference.