Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .cspell/custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,16 @@ zapatillas
yml
jwks
keyid
CAPI
dedup
Dedup
gbraid
gclid
Northbeam
reauth
reprepare
sandboxing
sess
tiktok
xjaw
WVLA
216 changes: 216 additions & 0 deletions docs/specification/event-context.md
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.

Copy link
Copy Markdown

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.

**Key features:**

- Pass structured UTM parameters for compatibility with existing analytics tools
- Provide deduplication keys so merchants can reconcile agentic transactions
Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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 ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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 (order.id or possibly even order.name) is a good dedupe candidate - but as you noted kind of a special case that's possible when a purchase is complete. In this case the flow works in the opposite direction e.g. business -> platform (instead of platform -> business for event_id). In the interest of simplicity I didn't include it here but those fields are available via UCP and, if platform and business align, they could also be used.

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.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add a callout for privacy:
e.g something like -

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 utm, dedup_keys, or custom fields should only be used for the purposes of attribution and conversion reporting as authorized by the user.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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.

2 changes: 2 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ nav:
- AP2 Mandates Extension: specification/ap2-mandates.md
- Buyer Consent Extension: specification/buyer-consent.md
- Discounts Extension: specification/discount.md
- Event Context Extension: specification/event-context.md
- Fulfillment Extension: specification/fulfillment.md
- Cart Capability:
- Overview: specification/cart.md
Expand Down Expand Up @@ -230,6 +231,7 @@ plugins:
- specification/ap2-mandates.md
- specification/buyer-consent.md
- specification/discount.md
- specification/event-context.md
- specification/fulfillment.md
Cart Capability:
- specification/cart.md
Expand Down
115 changes: 115 additions & 0 deletions source/schemas/shopping/event_context.json
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": {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both event_id and session_id are optional, making an empty dedup_keys: {} schema-valid and semantically meaningless. Should we add "minProperties": 1 to prevent this?

If dedup_keys is there, we should have alteast 1 additional property.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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": {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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?
If so, what would this mean with multi-item cart/checkout where multiple items were added

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mnaga good questions.

Per-request behavior: The extension uses ucp_request: "optional" on create and update operations, so the platform can include it on every request but isn't required to. In practice, I'd expect agents to send it when they want to model a new event — consider how current JS SDKs integrated with websites model events e.g.:

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 add_to_cart and remove_from_cart events from the Google spec above. @ashutosh-goog / @mnaga I sense this might be getting to an edge case outside the scope of UCP but just to test it out - if the UCP platform was going to make server-side calls back to the event reporting APIs of the agent ... would a single event_id be sufficient here (used with multiple event names). My sense is that modeling multiple event isn't necessary but welcome any pressure testing of this idea.

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. event_id likely would change with each UCP API call though allowing platforms to report distinct funnel events where needed (e.g. back to the agent alongside website traffic with appropriate dedupe keys and/or to 3P reporting tools like Triple Whale, NorthBeam, Fivetran, Criteo, etc)

"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"
}
]
}
}
}
}