-
Notifications
You must be signed in to change notification settings - Fork 336
feat: add event context extension for cart and checkout sessions #295
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,216 @@ | ||
| <!-- | ||
| Copyright 2026 UCP Authors | ||
|
|
||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||
| you may not use this file except in compliance with the License. | ||
| You may obtain a copy of the License at | ||
|
|
||
| http://www.apache.org/licenses/LICENSE-2.0 | ||
|
|
||
| Unless required by applicable law or agreed to in writing, software | ||
| distributed under the License is distributed on an "AS IS" BASIS, | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| See the License for the specific language governing permissions and | ||
| limitations under the License. | ||
| --> | ||
|
|
||
| # Event Context Extension | ||
|
|
||
| ## Overview | ||
|
|
||
| The Event Context extension enables referring platforms to pass referral context | ||
| and deduplication keys through agentic checkout flows. When a user discovers a | ||
| product through an external channel (a paid ad, an organic recommendation, an | ||
| influencer link, or an AI agent's suggestion) and completes a purchase via | ||
| agentic checkout, the merchant loses the referral context they normally receive | ||
| via URL parameters on their landing page. This extension preserves that data. | ||
|
|
||
| **Key features:** | ||
|
|
||
| - Pass structured UTM parameters for compatibility with existing analytics tools | ||
| - Provide deduplication keys so merchants can reconcile agentic transactions | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can txn-id for purchase and event-id for non-purchase be used for dedupes ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Certainly possible. Among the major conversion funnel reporting tools I was looking at there seemed to be some repeated use of event_id (uniquely identifying discrete events along a purchase journey - add to cart, start checkout, complete checkout) and some concept of sessions. The transaction id ( |
||
| with their server-side reporting | ||
| - Support any referring platform via reverse domain naming | ||
| - Pass platform-specific identifiers through an opaque `custom` field | ||
|
|
||
| **Dependencies:** | ||
|
|
||
| - Cart Capability or Checkout Capability | ||
|
|
||
| ## Discovery | ||
|
|
||
| Businesses advertise event context support in their profile: | ||
|
|
||
| ```json | ||
| { | ||
| "ucp": { | ||
| "version": "{{ ucp_version }}", | ||
| "capabilities": { | ||
| "dev.ucp.shopping.event_context": [ | ||
| { | ||
| "version": "{{ ucp_version }}", | ||
| "extends": "dev.ucp.shopping.cart", | ||
| "spec": "https://ucp.dev/{{ ucp_version }}/specification/event-context", | ||
| "schema": "https://ucp.dev/{{ ucp_version }}/schemas/shopping/event_context.json" | ||
| }, | ||
| { | ||
| "version": "{{ ucp_version }}", | ||
| "extends": "dev.ucp.shopping.checkout", | ||
| "spec": "https://ucp.dev/{{ ucp_version }}/specification/event-context", | ||
| "schema": "https://ucp.dev/{{ ucp_version }}/schemas/shopping/event_context.json" | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| ## Schema Composition | ||
|
|
||
| The event context extension extends both **cart** and **checkout** objects: | ||
|
|
||
| - **Base schemas extended**: `cart.json`, `checkout.json` | ||
| - **Path**: `cart.event_context`, `checkout.event_context` | ||
| - **Schema reference**: `event_context.json` | ||
|
|
||
| The `event_context` property is composed onto each object via `allOf`, | ||
| following the same extension pattern as `fulfillment.json` and `discount.json`. | ||
|
|
||
| ## Schema Definition | ||
|
|
||
| ### Event Context Payload | ||
|
|
||
| The `event_context` object contains referral context from the platform that | ||
| drove the cart or checkout: | ||
|
|
||
| | Field | Type | Required | Description | | ||
| |---------------|--------|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| | ||
| | `platform` | string | Yes | Referring platform identifier using reverse domain naming (e.g., `com.google`, `com.meta`) | | ||
| | `dedup_keys` | object | No | Deduplication keys for reconciling with the merchant's server-side reporting | | ||
| | `utm` | object | No | Standard UTM parameters for web analytics compatibility | | ||
| | `custom` | object | No | Platform-specific key-value pairs routed by the merchant based on the `platform` field. Values MUST be string, number, or boolean. Maximum 20 properties. | | ||
|
|
||
| ### Deduplication Keys | ||
|
|
||
| The `dedup_keys` object prevents double-counting when both the referring | ||
| platform and the merchant report the same transaction independently. If | ||
| present, at least one key MUST be provided: | ||
|
|
||
| | Field | Type | Description | | ||
| |--------------|--------|----------------------------------------------------------------------------------------| | ||
| | `event_id` | string | Shared dedup key for reconciling with the merchant's server-side reporting | | ||
| | `session_id` | string | Platform session identifier for cross-event correlation (e.g., `fbp`, `ga_session_id`) | | ||
|
|
||
| ### UTM Parameters | ||
|
|
||
| Standard UTM parameters for compatibility with web analytics tools (Google | ||
| Analytics, Northbeam, Triple Whale, etc.): | ||
|
|
||
| | Field | Type | Description | | ||
| |------------------------|--------|----------------------------------------------------------------------| | ||
| | `utm_source` | string | Traffic source | | ||
| | `utm_medium` | string | Marketing medium | | ||
| | `utm_campaign` | string | Campaign name | | ||
| | `utm_content` | string | Content identifier | | ||
| | `utm_term` | string | Search term | | ||
| | `utm_id` | string | Campaign ID | | ||
| | `utm_source_platform` | string | Advertising platform that served the ad (e.g., Google, Meta, TikTok) | | ||
|
|
||
| ### Request Behavior | ||
|
|
||
| The `event_context` property supports the following operations: | ||
|
|
||
| | Operation | Behavior | Description | | ||
| |------------|------------|-------------------------------------------------| | ||
| | `create` | `optional` | Platform MAY include event context on create | | ||
| | `update` | `optional` | Platform MAY update event context | | ||
| | `complete` | `optional` | Platform MAY include event context on complete | | ||
|
|
||
| ## Privacy Note | ||
|
|
||
| This extension replaces referral context and conversion signals that | ||
| traditionally flow from the referring platform to the business via the | ||
| merchant's website. When a purchase occurs through an agentic flow, the website | ||
| is bypassed and these signals would otherwise be lost. While the fields | ||
| primarily carry marketing and campaign metadata, some values — such as click | ||
| identifiers and session identifiers in `dedup_keys` or `custom` — may be | ||
| considered advertising data subject to user consent under applicable privacy | ||
| regulations. | ||
|
|
||
| Implementations **MUST**: | ||
|
|
||
| - Only use event context data for the purposes of conversion measurement, | ||
| reporting, attribution, and analytics | ||
| - **NOT** transmit personally identifiable information (e.g., email addresses, | ||
| phone numbers, names) through any field in this extension | ||
| - Comply with applicable consent requirements for advertising and marketing | ||
| data in the jurisdictions where they operate | ||
|
|
||
| ## Usage Examples | ||
|
|
||
| ### Google (Google Ads / Gemini) | ||
|
|
||
| A user discovers a product through a Google Shopping ad and completes the | ||
| purchase via Gemini's agentic checkout: | ||
|
|
||
| ```json | ||
| { | ||
| "event_context": { | ||
| "platform": "com.google", | ||
| "dedup_keys": { | ||
| "event_id": "evt_abc123def456" | ||
| }, | ||
| "utm": { | ||
| "utm_source": "google", | ||
| "utm_medium": "cpc", | ||
| "utm_campaign": "spring_collection_2026", | ||
| "utm_content": "60123456789", | ||
| "utm_id": "18234567890", | ||
| "utm_source_platform": "Google" | ||
| }, | ||
| "custom": { | ||
| "click_id": "EAIaIQobChMI8bXe7...", | ||
| "ad_group_id": "142345678901", | ||
| "placement": "Google_Shopping", | ||
| "gbraid": "WVLA4QjBkaJkZW..." | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The merchant includes this `event_id` when reporting the conversion via their | ||
| server-side integration to prevent double-counting. | ||
|
|
||
| ### Meta | ||
|
|
||
| A user discovers a product through Meta's platform and their AI agent completes | ||
| the purchase: | ||
|
|
||
| ```json | ||
| { | ||
| "event_context": { | ||
| "platform": "com.meta", | ||
| "dedup_keys": { | ||
| "event_id": "evt_abc123def456", | ||
| "session_id": "fb.1.1710300000000.1234567890" | ||
| }, | ||
| "utm": { | ||
| "utm_source": "meta", | ||
| "utm_medium": "paid_social", | ||
| "utm_campaign": "spring_sale_2026", | ||
| "utm_content": "6861203971771", | ||
| "utm_id": "6861196821371", | ||
| "utm_source_platform": "Meta" | ||
| }, | ||
| "custom": { | ||
| "click_id": "IwY2xjawOR56Fle...", | ||
| "placement": "Meta_AI" | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| The merchant passes `event_id` and `fbp` (from `session_id`) to their | ||
| Conversions API integration. The shared `event_id` prevents duplicate event | ||
| counting between the platform's first-party event and the merchant's server-side | ||
| event. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we add a callout for privacy: Privacy Note:Platforms and Businesses implementing this extension SHOULD ensure that the transmission of attribution data complies with applicable privacy laws and the user's consent preferences. Data passed via the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good callout ... let me think about this a bit - the data flowing through here is ideally unrelated to the user (e.g. not derived from the user or user identifiable) but rather a flow between the agent and the business to replace data that normally flows via the website.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Alright added some language to reinforce the privacy posture of this extension ... definitely open to more tweaks on the language but was trying to find something striking a reasonable balance of firmness without being anchored or implying any specific jurisdictions/ regulations / privacy policy / terms of service etc. |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,115 @@ | ||
| { | ||
| "$schema": "https://json-schema.org/draft/2020-12/schema", | ||
| "$id": "https://ucp.dev/schemas/shopping/event_context.json", | ||
| "name": "dev.ucp.shopping.event_context", | ||
| "title": "Event Context Extension", | ||
| "description": "Extends Cart and Checkout with event context, enabling referring platforms to pass referral context and deduplication keys through agentic checkout flows.", | ||
| "$defs": { | ||
| "event_context_payload": { | ||
| "type": "object", | ||
| "required": ["platform"], | ||
| "properties": { | ||
| "platform": { | ||
| "$ref": "types/reverse_domain_name.json", | ||
| "description": "Referring platform identifier (reverse domain naming). MUST correspond to the domain of the platform's UCP-Agent profile URL.", | ||
| "examples": ["com.google", "com.meta", "com.tiktok", "com.openai"] | ||
| }, | ||
| "dedup_keys": { | ||
| "type": "object", | ||
| "description": "Deduplication keys for reconciling this event with the merchant's own server-side reporting. Without these, the same transaction may be counted twice in analytics and reporting platforms.", | ||
| "minProperties": 1, | ||
| "properties": { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both If
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense - updated |
||
| "event_id": { "type": "string", "description": "Shared dedup key. The merchant includes this same event_id when reporting the event via their server-side integration (e.g., CAPI, Enhanced Conversions, Events API) to prevent double-counting." }, | ||
| "session_id": { "type": "string", "description": "Platform session identifier for cross-event correlation (e.g., fbp, ga_session_id)." } | ||
| } | ||
| }, | ||
| "utm": { | ||
| "type": "object", | ||
| "description": "Standard UTM parameters for compatibility with web analytics tools (Google Analytics, Northbeam, Triple Whale, etc.).", | ||
| "properties": { | ||
| "utm_source": { "type": "string" }, | ||
| "utm_medium": { "type": "string" }, | ||
| "utm_campaign": { "type": "string" }, | ||
| "utm_content": { "type": "string" }, | ||
| "utm_term": { "type": "string" }, | ||
| "utm_id": { "type": "string" }, | ||
| "utm_source_platform": { "type": "string" } | ||
| } | ||
| }, | ||
| "custom": { | ||
| "type": "object", | ||
| "description": "Platform-specific key-value pairs not covered by the structured fields above. Merchants pass these through to their analytics integrations based on the platform field.", | ||
| "additionalProperties": { | ||
| "type": ["string", "number", "boolean"] | ||
| }, | ||
| "maxProperties": 20 | ||
| } | ||
| } | ||
| }, | ||
| "dev.ucp.shopping.cart": { | ||
| "title": "Cart with Event Context", | ||
| "description": "Cart extended with referral event context.", | ||
| "allOf": [ | ||
| { | ||
| "$ref": "cart.json" | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "event_context": { | ||
| "$ref": "#/$defs/event_context_payload", | ||
| "description": "Referral event context from the platform that drove the cart.", | ||
| "ucp_request": { | ||
| "create": "optional", | ||
| "update": "optional" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| "dev.ucp.shopping.checkout": { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should attribution extension be applied to Cart as well, in addition to Checkout? Please see discounts extension as an example where it can extend both cart and checkout. In future, it could extend other events as well, but for now maybe starting with Cart and Checkout is a good idea. What do you think?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forgot to note it here earlier but did update the PR for this already. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would/should this be sent with every request one the Agent identifies the checkout session was initiated by an Event?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mnaga good questions. Per-request behavior: The extension uses
This actually raises an interesting consideration: a single UCP API call could map to what the website would model as multiple analytics events — e.g., a cart update that adds one item and removes another would map to both an Multi-item carts: I'm imagining that much of the event context e.g. the important UTM params won't vary across a UCP session. The dedupe data e.g. |
||
| "title": "Checkout with Event Context", | ||
| "description": "Checkout extended with referral event context.", | ||
| "allOf": [ | ||
| { | ||
| "$ref": "checkout.json" | ||
| }, | ||
| { | ||
| "type": "object", | ||
| "properties": { | ||
| "event_context": { | ||
| "$ref": "#/$defs/event_context_payload", | ||
| "description": "Referral event context from the platform that drove the checkout.", | ||
| "ucp_request": { | ||
| "create": "optional", | ||
| "update": "optional", | ||
| "complete": "optional" | ||
| } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| }, | ||
| "dev.ucp.shopping.event_context": { | ||
| "platform_schema": { | ||
| "title": "Event Context Capability (Platform)", | ||
| "description": "Platform-level event context capability. Indicates the platform can provide referral event context on cart and checkout requests.", | ||
| "allOf": [ | ||
| { | ||
| "$ref": "../capability.json#/$defs/platform_schema" | ||
| } | ||
| ] | ||
| }, | ||
| "business_schema": { | ||
| "title": "Event Context Capability (Business)", | ||
| "description": "Business-level event context capability. Indicates the business accepts and processes referral event context.", | ||
| "allOf": [ | ||
| { | ||
| "$ref": "../capability.json#/$defs/business_schema" | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Completely agree on the premise hence the suggestion to supply this information as part of event context rather than as attribution information.