> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Record a Shopify cart receipt attributed to a chat conversion

> Writes a cart_attribution_confirmed widget analytics event keyed by cart_attribution:<conversionId>:<action>:<variantId|productId|cartToken|cart> so retries…

Writes a `cart_attribution_confirmed` widget analytics event keyed by
`cart_attribution:&lt;conversionId>:&lt;action>:&lt;variantId|productId|cartToken|cart>` so
retries are idempotent (`duplicate: true`).

Widget identity is verified when signing is configured; tokenless compatibility does not establish tenant ownership. See the authentication and recovery guide for credential and retry rules.

### Request body

`CartAttributionReceipt`

**conversionId** `string` *required*

Maximum length: `160`.

**sessionId** `string` *required*

Maximum length: `160`.

**action** `string` *required*

Allowed values: `'add_to_cart'`, `'checkout'`, `'view'`.

**threadId** `string`

Maximum length: `160`.

**cartToken** `string`

Maximum length: `255`.

**productId** `string`

Maximum length: `255`.

**productTitle** `string`

Maximum length: `255`.

**variantId** `string`

Maximum length: `255`.

**source** `string`

Default: `'response-chat-widget'`. Maximum length: `80`.

**landingPage** `string`

Maximum length: `500`.

**referrer** `string`

Maximum length: `500`.

**occurredAt** `string (date-time)`

**orgId** `string`

Used only when the widget token carries no org id.

**agentId** `string`

### Response

`object`

**ok** `boolean` *required*

Fixed value: `true`.

**duplicate** `boolean` *required*

**eventId** `string` *required*

The idempotency key of the stored event.

### Status codes

| Code | Meaning |
| - | - |
| `200` | Receipt stored (or already stored) |
| `400` | Missing `conversionId`, `sessionId`, `action` or org id |
| `401` | Widget token missing, malformed, expired, from the future, or badly signed |
| `403` | Request org/agent disagrees with the widget token claims |
| `429` | Too many requests for this IP (scoped by verified org/agent) |
| `500` | Unhandled error |
| `502` | Analytics store unavailable or rejected the write |

### Using this contract

Read the [source OpenAPI document](https://docs.stateset.com/spec/chat-widget.json) for declared schemas and alternatives.
This page also includes documented corrections from the [spec overlays](https://github.com/stateset/docs/tree/main/spec/overlays).
Example IDs and values are illustrative; replace them with records from your workspace.

```bash cURL theme={null}
curl --silent --show-error --fail-with-body --request POST \
  --url 'https://api.example.com/api/cart-attribution' \
  --header 'x-widget-token: YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
  "conversionId": "string",
  "sessionId": "string",
  "action": "add_to_cart",
  "threadId": "string",
  "cartToken": "YOUR_API_KEY",
  "productId": "string",
  "productTitle": "string",
  "variantId": "string",
  "source": "response-chat-widget",
  "landingPage": "string",
  "referrer": "string",
  "occurredAt": "2026-08-31T14:22:05Z",
  "orgId": "string",
  "agentId": "string"
}'
```

```json 200 theme={null}
{
  "ok": true,
  "duplicate": true,
  "eventId": "string"
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.