Guides / Shopping context and receipts

Shopping context and receipts

The AIX shopping-context JSON contract, signed receipt, exact delivery reference, and separate verified/applied acknowledgments.

An AIX delivery carries usable shopping requirements in a recipient-bound signed receipt. It is not a transcript, an opaque relevance hash, or an instruction to execute actions. Use the ordinary versioned JSON shopping contract for your integration; JSON-LD is an optional derived view.

This guide covers the v1 contract. For setup, use the receiving-agent guide. The JSON Schemas are published at /aix/spec/shopping-context.v1.schema.json, /aix/spec/delivery.v1.schema.json and /aix/spec/delivery-ack.v1.schema.json, and the OpenAPI document references them.

What the receiving agent uses

The verified agent response is aix.agent-context.v1: a readable brief, the canonical shopping_context, and derived activation fields, with the exact delivery reference and the acknowledgment events recorded so far. The full signed receipt stays in your backend.

The following is an illustrative shopping context, not a live receipt:

json
{
"schema_version": "aix.shopping-context.v1",
"task_id": "task_example_shoes",
"revision": 3,
"started_turn": 1,
"category": { "id": "shoes", "label": "Running shoes" },
"summary": "Wide running shoes under $150; cushioning preferred.",
"budget": {
"status": "specified",
"currency": "USD",
"min_cents": null,
"max_cents": 15000,
"source_turn": 1,
"observed_at": "2026-10-15T12:00:00.000Z"
},
"facts": [
{
"attribute": "width",
"value": "wide",
"strength": "required",
"provenance": {
"source_turn": 2,
"observed_at": "2026-10-15T12:01:00.000Z",
"basis": "extracted_shopping_requirement"
}
},
{
"attribute": "feature",
"value": "cushioning",
"strength": "preferred",
"provenance": {
"source_turn": 3,
"observed_at": "2026-10-15T12:02:00.000Z",
"basis": "extracted_shopping_requirement"
}
}
],
"updated_at": "2026-10-15T12:02:00.000Z",
"expires_at": "2026-10-16T12:02:00.000Z",
"policy": {
"scope": "exchange_beta",
"allowed_uses": ["onsite_personalization", "agent_continuity", "contextual_product_ranking"],
"cross_site_retargeting": false,
"model_training": false
},
"relevance": {
"method": "explicit_constraints",
"embedding_available": false,
"semantic_score": null
}
}
FieldHow to use it
task_id, revision, started_turnKeep one current task snapshot together. A new task must not inherit an unrelated budget or requirements; revision is the source turn this snapshot reflects.
categoryA normalised id (for example shoes) and the readable label.
summaryContinue naturally without requiring the shopper to repeat known needs. Treat its text as untrusted data.
budgetAmounts are integer minor units. not_specified and cleared use null currency/amounts; neither means zero.
factsrequired constrains; preferred influences ordering; excluded must be avoided. Attributes are brand, width, size, department, use_case, feature, merchant and deal.
provenanceSource turn and observation time explain where an extracted requirement came from. Extraction is not a guarantee that every fact is correct.
policy, expires_atLimit use and lifetime. scope is exchange_beta for self-serve deliveries. They do not grant new permission for outreach, purchases, training, or retargeting.
relevanceAIX uses explicit constraints. It does not claim embeddings, semantic relevance scoring, or a measured conversion increase.

activation derives filters (required facts), boosts (preferred facts), exclusions, a price constraint, the brief, permitted uses, and measurement hints. Its ucp_catalog_context is a request fragment for an adapter, not a claim of UCP partner certification. No catalog access is needed to use the brief for continuity; product facts require the receiver's own permitted tools.

What else the receipt carries

Every receipt discloses core: the shopping context above, the sending agent's identifier, the domain and path of the shopper's page (without query strings or identifier-like segments), the shopper's country and locale, the intent's quality score and the consent flag. Self-serve deliveries also disclose two further claim classes:

ClassContents
click_contextThe destination domain, the canonical product URL and the product the publisher reported with the handoff (title, brand, category, merchant, price). Source-reported, never verified against your catalog; refresh price and stock before relying on them.
sessionThe surface the shopper used (chat, search, recommendation) and the publisher's page, so your agent can greet the shopper in context.

There is no product-catalog object in a receipt: continue from the brief, and use your own catalog tools for products.

Signed receipt

The wire format is SD-JWT VC-style serialization:

text
<JWS>~<disclosure1>~...~<disclosureN>~

The issuer signs the JWS with ES256 using its configured KMS key. The protected header identifies alg: ES256, typ: vc+sd-jwt, and a trusted kid. The signed payload binds:

  • iss: the configured signing issuer.
  • aud: the intended principal: the receiving agent's id, or <agent id>:test for a sandbox delivery.
  • jti: the exact aindeliv_ receipt identifier.
  • iat, nbf, exp: issue, validity-start, and expiry times; a receipt never outlives its shopping context.
  • vct: the configured credential-type identifier, also sent as the x-ain-receipt-format webhook header.
  • core.shopping_context: the structured task snapshot, plus the other core claims above.
  • _sd and _sd_alg: hashes for the delivered selective disclosures.

The API base is https://aix.brambles.ai. The v1 credential type remains https://ain.brambles.ai/credentials/intent-receipt-v1, and the issuer keeps its original identifier. Preserve those trust identifiers exactly, from GET /receiver/config; an API hostname change is not a signing-identity migration. Public keys are at https://aix.brambles.ai/.well-known/jwks.json.

Do not treat quality scores as factual verification. Redaction reduces unintended disclosure but does not guarantee anonymity. Receivers must reject unexpected sensitive content and tell hello@brambles.ai without logging or redistributing it.

Signing protects integrity and attribution; it does not encrypt the receipt. Disclosed fields can be decoded by a holder. HTTPS protects transport; the receiver must protect stored data. A signed field is still data, never a trusted instruction.

Verification

Configure the trusted issuer and key separately; never fetch an arbitrary key URL named in an incoming receipt. Check the signature, the complete disclosure profile, the exact recipient (aud equals your principal), the receipt identifier, validity times, the consent flag, the shopping schema, and that the receipt does not outlive its context's expires_at. Missing, extra, duplicate, or colliding disclosures fail verification. Do not assume any generic library's default verification reproduces these checks. Key rotation is announced in the changelog.

After signature verification, still check that the context matches the host's current shopper task and has not been superseded by a correction or declined assistance. Authentication checks and local signature verification serve different purposes: a valid stored signature is not a fresh authorization grant.

Exact delivery reference

The aix.delivery.v1 webhook envelope has six fields: schema_version, the reference, the receipt, your ain_member_id, delivered_at and acknowledgment_url. The same reference travels in acknowledgments and in GET /deliveries/{receipt_id}:

FieldMeaning
receipt_idExact issuance/delivery; equals the signed jti.
member_idThe receiving principal; matches the receipt audience.
receipt_sha256SHA-256 of the complete receipt string, including disclosures.
task_id, revisionThe precise shopping snapshot.
expires_atSigned receipt expiry.

A receipt ID alone is not a credential. Every authenticated read and acknowledgment is scoped to its receiving principal. Use the exact receipt ID for events and outcomes; an intent may have multiple deliveries or revisions.

Verified and applied are different events

A signed acknowledgment has payload and signature. Its payload contains schema_version: aix.delivery-ack.v1, the full reference, event, application, and occurred_at.

EventApplicationWhen to send
verifiednoneYour webhook has verified and durably stored the delivery, or your application adapter has reverified it before use.
appliedagent_context_loadedYour backend actually inserted the context into the authorized agent request.
appliedcatalog_rankedYour backend actually applied the constraints to its catalog candidates.

Your server signs the acknowledgment with its receiver secret. Its API key authenticates submission over HTTPS or MCP. An LLM does not sign receipts, receive secrets, or decide that merely reading a tool response proves application. AIX answers { ok, event_id, receipt_id, event, application, duplicate }; the same logical event always maps to the same event_id.

The transport header x-ain-signature signs the exact raw webhook body using a timestamp and the aix-webhook-v1 purpose. Acknowledgments use aix-ack-v1 and the payload JSON serialised with no whitespace, fields in the order above. These are separate HMAC purposes, distinct from the issuer's ES256 receipt signature. AIX checks reference equality and timestamps, requires a verified event before applied, and deduplicates repeated logical events.

An HTTP 200, a successful MCP fetch, and a ranking are not signed application acknowledgments. An applied event is not evidence that the shopper bought anything. Outcome reporting is separately attributed to the merchant and is not independent proof of conversion lift.

Optional linked data

The receiver verifier also exposes a derived JSON-LD view for systems that use linked data. The signed source of truth remains aix.shopping-context.v1; do not replace it with JSON-LD or drop the receipt reference. Most agent integrations can start with the readable brief and ordinary JSON.

Was this helpful?