Developers/Core objects
PROTOCOL SPEC

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.

Private utility
The pricing.floor_priceis the merchant-side analogue of the buyer's max budget — tagged PRIVATE_UTILITY. It must never appear on the wire. The router's payload check rejects any outbound envelope whose payload contains the sender's floor.
{
  "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.

The verified match
The MatchCertificateis the trust artifact behind a “verified match.” No buyer mints it, no merchant signs for itself — the platform attests, and disputes and settlement point back to the cert_idrather than to a screenshot of a cart. This single object is what makes VCP's match a fact in the audit log instead of an unverifiable claim.
{
  "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.

Design of record, private beta
These object schemas are the design of record — stable enough to build against and reason about precisely. The running system that issues match certificates and materializes state diffs is in private beta and not generally available.