Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
54 changes: 53 additions & 1 deletion docs/specification/catalog/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,13 @@ Messages communicate business outcomes and provide context:
| Type | When to Use | Example Codes |
| :--- | :--- | :--- |
| `error` | Business-level errors | `NOT_FOUND`, `OUT_OF_STOCK`, `REGION_RESTRICTED` |
| `warning` | Important conditions affecting purchase | `DELAYED_FULFILLMENT`, `FINAL_SALE`, `AGE_RESTRICTED` |
| `warning` | Important conditions affecting purchase | `DELAYED_FULFILLMENT`, `FINAL_SALE` |
| `info` | Additional context without issues | `PROMOTIONAL_PRICING`, `LIMITED_AVAILABILITY` |

Warnings with `disclosure: true` carry item-anchored notices (e.g., allergen
declarations, safety warnings) that platforms must not hide or dismiss. See
[Disclosures](../checkout.md#disclosures) for the full rendering contract.

**Note**: All catalog errors use `severity: "recoverable"` - agents handle them programmatically (retry, inform user, show alternatives).

#### Message (Error)
Expand Down Expand Up @@ -250,6 +254,54 @@ identifiers were not found.
Agents correlate results using the `inputs` array on each variant. See
[Client Correlation](lookup.md#client-correlation).

#### Product Disclosure

When a product requires a disclosure (e.g., allergen notice, safety warning),
return it as a warning with `disclosure: true`. The `path` field targets the
relevant component in the response — when it targets a product, the
disclosure applies to all of its variants.

```json
{
"ucp": {...},
"products": [
{
"id": "prod_nut_butter",
"title": "Artisan Nut Butter Collection",
"variants": [
{
"id": "var_almond",
"title": "Almond Butter",
"price": { "amount": 1299, "currency": "USD" },
"availability": { "available": true }
},
{
"id": "var_cashew",
"title": "Cashew Butter",
"price": { "amount": 1499, "currency": "USD" },
"availability": { "available": true }
}
]
}
],
"messages": [
{
"type": "warning",
"code": "allergens",
"path": "$.products[0]",
"content": "**Contains: tree nuts.** Produced in a facility that also processes peanuts, milk, and soy.",
"content_type": "markdown",
"disclosure": true,
"image_url": "https://merchant.com/allergen-tree-nuts.svg",
"url": "https://merchant.com/allergen-info"
}
]
}
```

See [Disclosures](../checkout.md#disclosures) for the full rendering
contract.

## Transport Bindings

The capabilities above are bound to specific transport protocols:
Expand Down
105 changes: 105 additions & 0 deletions docs/specification/checkout.md
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,111 @@ payment instrument, or by removing the claim from `context.eligibility` to
renegotiate the checkout (obtaining updated pricing, availability, etc.)
and then resubmitting for completion.

### Disclosures

Warning messages with `disclosure: true` carry item-anchored notices —
safety warnings, allergen declarations, compliance content, etc. — that
**MUST** follow the prescribed rendering contract below. The `disclosure`
flag signals that the warning **MUST NOT** be treated as a dismissible
notice.

#### Platform Requirements

When a warning has `disclosure: true`:

* **MUST** display the warning `content` to the buyer.
* **MUST** display the warning in proximity to the component referenced by
`path`, preserving the association between the disclosure and its subject.
When `path` is omitted, the disclosure applies to the response as a whole.
* **MUST NOT** hide, collapse, or auto-dismiss the warning.
* **MUST** render `image_url` when present (e.g., warning symbol,
energy class label).
* **SHOULD** render `url` as a navigable reference link when present.

Warnings with `disclosure: true` **SHOULD** be given rendering priority
over regular warnings.

#### Business Requirements

* **MUST** set `disclosure: true` when the warning content must be displayed
alongside a specific item and must not be hidden or auto-dismissed.
* **SHOULD** use the `path` field to associate disclosures with the
relevant component in the response.
* **SHOULD** provide a `code` that identifies the disclosure category
(e.g., `prop65`, `allergens`, `energy_label`).
* **SHOULD** provide `image_url` when the disclosure has an associated
visual element (e.g., warning symbol, energy class label).
* **SHOULD** provide `url` when a reference link is available for the
buyer to learn more.

#### Disclosure vs Acknowledgment

A warning with `disclosure: true` is a presentation mechanism — it
controls how the warning is rendered, not whether the checkout can
proceed. When affirmative buyer acknowledgment or authorization is also
required, the business **MAY** combine the disclosure with the escalation
mechanisms described in the
[Checkout Status Lifecycle](#checkout-status-lifecycle) to ensure the
appropriate buyer input is obtained.

#### Jurisdiction and Applicability

It is the business's responsibility to determine which disclosures apply
to a given session and return only those that are relevant. Businesses
**SHOULD** use buyer-provided data (`context` and other inputs) and
product attributes to resolve jurisdiction-specific requirements.
Platforms do not affect or resolve disclosure applicability — they render
what they receive from the business.

#### Example

A checkout response containing both a recoverable error and a disclosure
warning on a line item:

```json
{
"ucp": { "version": "{{ ucp_version }}", "status": "success" },
"id": "chk_abc123",
"status": "incomplete",
"currency": "USD",
"line_items": [
{
"id": "li_1",
"item": { "id": "item_456", "title": "Artisan Nut Butter Collection", "image_url": "https://merchant.com/nut-butter.jpg" },
"quantity": 1,
"totals": [{ "type": "subtotal", "amount": 1299 }]
}
],
"totals": [{ "type": "total", "amount": 1299 }],
"messages": [
{
"type": "error",
"code": "missing",
"path": "$.buyer.email",
"content": "Buyer email is required",
"severity": "recoverable"
},
{
"type": "warning",
"code": "allergens",
"path": "$.line_items[0]",
"content": "**Contains: tree nuts.** Produced in a facility that also processes peanuts, milk, and soy.",
"content_type": "markdown",
"disclosure": true,
"image_url": "https://merchant.com/allergen-tree-nuts.svg",
"url": "https://merchant.com/allergen-info"
}
],
"links": []
}
```

The platform resolves the recoverable error programmatically while rendering
the allergen disclosure in proximity to the referenced line item. Platforms
that cannot honor the disclosure rendering contract **MUST** escalate to
merchant UI via `continue_url` rather than silently downgrading to a
regular warning.

## Continue URL

The `continue_url` field enables checkout handoff from platform to business UI,
Expand Down
15 changes: 15 additions & 0 deletions source/schemas/shopping/types/message_warning.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@
],
"default": "plain",
"description": "Content format, default = plain."
},
"disclosure": {
"type": "boolean",
"default": false,
"description": "When true, this warning carries a disclosure that MUST be displayed in proximity to the referenced component and MUST NOT be hidden or auto-dismissed."
},
"image_url": {
"type": "string",
"format": "uri",
"description": "URL to a required visual element (e.g., warning symbol, energy class label)."
},
"url": {
"type": "string",
"format": "uri",
"description": "Reference URL for more information (e.g., regulatory site, registry entry, policy page)."
}
}
}
Loading