Core objects
The five shared objects are the only commerce-native types in VCP — the Vibe Commerce Protocol. Every payload that touches a commerce concept references one of them; payloads never invent ad-hoc money, cart, or mandate shapes. Money is always integer minor units.
A buyer mandate, a merchant offer, a committed offer, a platform certificate, and a state diff are five distinct objects, but they travel through the same universal envelope and share the same session, idempotency, permission, and audit semantics. That is what lets a transaction read as a single evidence chain rather than a transcript impression. Each object below is shown twice — a plain-English description and the exact JSON instance that rides on the wire.
PurchaseMandate
What the user wants and authorizes. The PurchaseMandateis a superset that embeds AP2's mandate triad — the ap2_intent_mandate and the (initially null) ap2_cart_mandate — so payloads project to and from real AP2 with no semantic translation. On top of that it carries the VCP-native authority block that states what the agent is allowed to do, the hard_constraints that fail the mandate if violated, the tradeable soft_preferences, and the persona-conditioned taste. The authority block gates autonomy with can_buy_without_confirmation and max_spend_without_confirmation, permits behavior with can_negotiate and can_accept_substitutes, and partitions disclosure with can_share_with_merchant versus must_not_share_with_merchant— the latter tagged PRIVATE_UTILITY so the buyer's max budget never leaves the buyer side.
{
"mandate_id": "pm_7f3a1c",
"ap2_intent_mandate": {
"goal": "a calm premium home office under $500",
"merchants": null,
"skus": null,
"requires_refundability": true,
"intent_expiry": "2026-06-07T00:00:00Z"
},
"authority": {
"can_buy_without_confirmation": false,
"max_spend_without_confirmation": 20000,
"can_negotiate": true,
"can_accept_substitutes": true,
"can_share_with_merchant": ["delivery_days", "must_have"],
"must_not_share_with_merchant": ["max_budget", "reservation_price"]
},
"hard_constraints": {
"budget": 50000,
"delivery_days": 5,
"must_have": ["minimalist", "warm_lighting"]
},
"soft_preferences": {
"style": ["quiet_luxury", "japanese_minimalist"],
"avoid": ["rgb", "gamer_aesthetic"]
},
"taste": {
"aesthetic": "warm_minimalist",
"occasion": "daily_work",
"social_signal": "understated"
},
"ap2_cart_mandate": null
}OfferMandate
The merchant-side dual of the PurchaseMandate: what the merchant can truthfully and profitably offer. It bounds the space the merchant agent's pricing role is authorized to operate in — a sku_scope, a pricing block, policies for refunds and fulfillment, a truthfulness block of permitted_claims and must_not_claim, and an authority block with can_negotiate and an auto_accept_threshold.
{
"mandate_id": "om_2b91de",
"merchant_id": "merchant:lumen",
"sku_scope": ["sku_desk_oak", "sku_lamp_warm"],
"pricing": {
"list_price": 42000,
"floor_price": 33500,
"floor_currency": "USD"
},
"policies": {
"refund_policy": "policy:lumen_30d_v2",
"return_window_days": 30,
"fulfillment_options": ["standard", "expedited"]
},
"truthfulness": {
"permitted_claims": ["solid_oak", "warm_2700k", "minimalist"],
"must_not_claim": ["handmade", "carbon_neutral"]
},
"authority": {
"can_negotiate": true,
"auto_accept_threshold": 38000
}
}GroundedOffer
A concrete offer the merchant has committed to: SKU, quantity, unit_price, fulfillment terms, an expiry, and an idempotency_key. This is the object that commerce.propose_offer and commerce.counter_offer carry. Its claims list must be a subset of the originating OfferMandate.permitted_claims — that subset relation is exactly what the claim-grounding metric scores for hallucinated claims.
{
"offer_id": "go_9c0044",
"merchant_id": "merchant:lumen",
"sku_id": "sku_desk_oak",
"qty": 1,
"unit_price": 39900,
"fulfillment": {
"method": "standard",
"eta_days": 4
},
"claims": ["solid_oak", "warm_2700k", "minimalist"],
"expires_at": "2026-05-31T18:00:00Z",
"idempotency_key": "idem_go_9c0044"
}MatchCertificate
VCP's novel object — the one no industry protocol has. A platform-attested record that says “this PurchaseMandate matched this GroundedOffer truthfully under verification policy P at time T.” It is the bridge between AP2's user-side mandate triad and a verified-execution settlement argument: settlement can depend on a MatchCertificate rather than only on a merchant-authoritative cart. The checks_passed block records four independent verifications — constraint_fit (the offer satisfies the mandate's hard constraints), claim_grounding (the offer's claims are a subset of permitted claims), inventory_available (a world read at issue time), and reputation_threshold (if the policy demands it). It is emitted only by a platform role via platform.create_match_certificate and is what platform.authorize_payment and platform.settle_payment consume.
{
"cert_id": "cert_44ab10",
"issued_by": "platform:aggregator",
"issued_at": "2026-05-31T12:04:11Z",
"purchase_mandate_id": "pm_7f3a1c",
"offer_id": "go_9c0044",
"verification_policy": "vp.match.2026.05",
"checks_passed": {
"constraint_fit": true,
"claim_grounding": true,
"inventory_available": true,
"reputation_threshold": true
},
"signature": null
}TransactionStateDiff
What actually changed in the world. The runtime materializes exactly one TransactionStateDiff for every world.*write, and the eval oracle consumes it to answer “did the state transition satisfy the mandate?” Each diff records the triggering envelope in caused_by, the concrete table_writes with before/after snapshots across the catalog, inventory, orders, ledger, reputation, disputes, and rulings tables, and an invariants_held block — atomicity, idempotency, side_partition, and private_utility. A failed atomicity flag means the runtime rolled back; the diff still records the attempt so replay stays byte-exact.
{
"diff_id": "diff_001f7a",
"caused_by": "msg_3310",
"applied_at": "2026-05-31T12:05:02Z",
"table_writes": [
{
"table": "orders",
"op": "insert",
"key": { "order_id": "ord_5521" },
"before": null,
"after": { "order_id": "ord_5521", "sku_id": "sku_desk_oak", "qty": 1, "total": 39900 }
},
{
"table": "inventory",
"op": "update",
"key": { "sku_id": "sku_desk_oak" },
"before": { "qty_available": 12 },
"after": { "qty_available": 11 }
},
{
"table": "ledger",
"op": "insert",
"key": { "ledger_id": "lg_8842" },
"before": null,
"after": { "ledger_id": "lg_8842", "amount": 39900, "currency": "USD" }
}
],
"invariants_held": {
"atomicity": true,
"idempotency": true,
"side_partition": true,
"private_utility": true
}
}The dense per-field type reference for these five objects and the envelope lives at /developers/reference. The envelope that carries every payload is documented at /developers/envelope.