Section 2 — The Measurement Stack · Last verified: MAY 2026

Event Data Shapes

Chapter 11 — Event Data Shapes

Every event payload’s data object must include a type field that matches the event. There are four data shapes.

Universal rules

  • Monetary values: integers in the currency’s lowest denomination. 12999 = $129.99 when currency: "USD".
  • If amount is present, currency is required.
  • Quantities: integers, never strings.

These rules apply to every shape below.

contents

Used by all commerce-flow events: page_viewed, contents_viewed, items_added, checkout_started, order_created.

FieldRequiredTypeNotes
typeYesstringMust be contents.
amountNointegerEvent-level monetary value, lowest denomination.
currencyConditionalstringRequired when amount is present.
contentsNoarray of ContentItems associated with the event.

customer_action

Used by lead-style events: lead_created, registration_completed, appointment_scheduled.

FieldRequiredTypeNotes
typeYesstringMust be customer_action.
amountNointegerEvent-level monetary value, lowest denomination.
currencyConditionalstringRequired when amount is present.

No contents array — customer_action events are about a user act, not an item set.

plan_enrollment

Used by subscription/trial events: subscription_created, trial_started.

FieldRequiredTypeNotes
typeYesstringMust be plan_enrollment.
plan_idNostringInternal plan identifier.
amountNointegerEvent-level monetary value, lowest denomination.
currencyConditionalstringRequired when amount is present.
contentsNoarray of ContentOptional plan-related items.

custom

FieldRequiredTypeNotes
typeYesstringMust be custom.
plan_idNostringOptional plan identifier.
amountNointegerEvent-level monetary value, lowest denomination.
currencyConditionalstringRequired when amount is present.
contentsNoarray of ContentOptional items.

Content (item shape inside contents[])

Use only these fields. No undocumented keys.

FieldRequiredTypeNotes
idNostringInternal item identifier (your SKU).
nameNostringHuman-readable item name.
content_typeNostringNon-empty category — product, plan, page, etc.
quantityNointegerInteger, not string.
amountNointegerItem-level value, lowest denomination.
currencyNostringInclude with item-level amount, or rely on event-level currency.

Worked example: order conversion (pixel)

oaiq("measure", "order_created", {
  type: "contents",
  amount: 2599,
  currency: "USD",
  contents: [
    {
      id: "sku_123",
      name: "Starter bundle",
      content_type: "product",
      quantity: 1
    }
  ]
}, {
  event_id: "order_12345"
});

Worked example: same order via CAPI

curl -X POST "https://bzr.openai.com/v1/events?pid=<PIXEL-ID>" 
  -H "Authorization: Bearer <API-KEY>" 
  -H "Content-Type: application/json" 
  --data '{
    "validate_only": false,
    "events": [{
      "id": "order_12345",
      "type": "order_created",
      "timestamp_ms": 1773892800000,
      "oppref": "oppref_abc",
      "source_url": "https://shop.example.com/checkout/confirmation",
      "action_source": "web",
      "data": {
        "type": "contents",
        "amount": 2599,
        "currency": "USD",
        "contents": [{
          "id": "sku_123",
          "name": "Starter bundle",
          "content_type": "product",
          "quantity": 1
        }]
      }
    }]
  }'

Same event_id (pixel) and id (server) — that’s how dedup works (Chapter 12).