carousell/rctp
Core conceptsRe-Commerce Trust ProfileDraft 0.4 · adopted for v0.2

RCTP Core Concepts

The Re-Commerce Trust Profile (RCTP) is an open profile of the Universal Commerce Protocol (UCP) and the Agent Payments Protocol (AP2) for person-to-person trade in second-hand goods, where one or both sides act through an AI agent. It defines only what UCP and AP2 leave open: negotiation, a seller's private limits, an enforcement decision on every agent call, and signed proof. Everything else is UCP.

Terminology

Seller and buyer are people. A seller agent or buyer agent acts for one of them; each is a UCP platform, run by an operator. The marketplace is the UCP business that hosts the listing, and in RCTP it is also the enforcement point that decides every agent call. Roles describe who acts for whom, not which company: one organisation may play several, and each role's duties apply in full.

Delegated by consent.People hand their agent the whole trade, with their consent, and can revoke it at any time.
Transparent profiles.Every seller and every unique item has a profile both sides can check.
Guardrails, enforced.The marketplace's gateway enforces the seller's limits on every call and keeps a signed record.

What RCTP solves

UCP is built around retail. A business publishes a price, stands behind the item as merchant of record, and an agent's job is to discover the offer and pay for it. A second-hand deal between two people breaks four of those assumptions at once.

Retail checkout (UCP)Second-hand deal (RCTP)So RCTP adds
PriceListed by the businessNegotiated between two peopleOffers, counters and Deal Terms
SellerA business running its own serverA person who must delegate to an agent that can be persuaded, injected or simply wrongA revocable Agent Grant with a tier per verb, and passkey approvals
LimitsPublic: the price is the priceSecret: whoever learns the lowest price wins, including through the seller's own agentListing Terms held by the marketplace; no agent ever receives them
TrustA merchant of record stands behind a new itemTwo strangers, one unique used item, nobody standing behind itFunds held until signed proof; a hash-chained deal record

The one party both people already trust is the marketplace. RCTP makes it the enforcement point: agents can be clever, but they cannot change a rule, see a secret, or move money. The marketplace holds the rules, applies them to every call, and signs what happened.

Key goals

Safe delegationA person can let an agent sell or buy for them without trusting it with anything that matters.
Private limitsThe seller's floor is enforced on every call and stated to no one: not the buyer, not any agent, not a log.
Agent-to-agent negotiationTwo agents agree the whole deal (price, delivery, payment), asynchronously, with expiry and revision.
Proof that moves moneyFunds are released or refunded only on signed events from the party that observed them.
Facts, not identitiesParties learn bands and attested facts about people and items, never names, addresses or numbers.
Minimal by designReuse UCP and AP2 wherever they define a verb or noun; extend by category through open values, not new protocol.

Roles & participants

RCTP names roles, never companies. Every agent call passes through the marketplace.

RCTP roles The seller and buyer each delegate to an agent. Both agents call the marketplace enforcement point, which holds the Listing Terms, decides each call and writes the deal record. The holder of funds and the carrier sign the events that move money. Seller sets terms · signs with passkey Seller agent UCP platform · Agent Grant delegates Buyer confirms what arrived Buyer agent UCP platform · AP2 mandate delegates Marketplace enforcement point · UCP business issues grants · holds Listing Terms decides every call · writes the deal record signed calls signed calls Holder of funds AP2 payee · signs money events Carrier · Attester signs what it observed
Agents never call each other directly. They meet at the marketplace, which is the only party that sees the private terms.

Seller & seller agent

UCP platform, acting under an Agent Grant

The seller sets their terms once, on a screen the marketplace hosts, and approves important steps with their own passkey. The agent lists items, answers buyers from structured facts, counters and accepts, within the verbs and tiers the seller granted.

Examples
A person selling a used phone; a listing assistant built by a partner.

Buyer & buyer agent

UCP platform, acting under the buyer's AP2 mandate

The agent finds listings, makes offers on Deal Terms, redeems the checkout and pays into protected payment. The buyer confirms what arrived, or rejects it with a reason.

Examples
A shopping assistant, a deal-hunting agent, a super-app.

Marketplace

UCP business · the enforcement point

Issues Agent Grants through its authorization server, holds Listing Terms, decides every agent call, signs the checkout an accepted offer becomes, and writes the deal record. It never lets an agent read private terms or change a grant.

Examples
Classifieds and resale marketplaces.

Holder of funds · carriers · attesters

Signers of the events that move money

The holder of funds (the AP2 payee) signs funds_held, released and refund, and releases only when the deal's condition holds. Carriers sign shipped and delivered. Attesters sign facts about items. Each signs only what it observed.

Examples
Marketplace escrow, a licensed payment partner, a courier, an inspector.

Core concepts

RCTP revolves around five constructs. Each answers one of the four broken assumptions, and none redefines anything UCP or AP2 already defines.

1

Agent Grant

The seller's permission for one agent to act for them on one marketplace.

A grant is UCP Identity Linking with RCTP scopes: an OAuth 2.0 authorization code with PKCE, where the consent screen names the agent, its operator, each verb with its tier, and the expiry. It asks for no prices. The access token is bound to the agent's signing key (cnf.jkt), so a stolen token is useless, and the marketplace looks the grant up on every call, so revocation takes effect on the very next one. A grant lives at most 90 days.

Each verb is a scope with an allowed set of tiers; the seller picks a tier within it. Two verbs have no scope at all, so no grant can ever allow them (see Capabilities & verbs).

2

Listing Terms

The seller's private negotiating envelope for one item, held and enforced by the marketplace.

When the seller agent proposes a listing, the marketplace asks the seller to approve it on a hosted page. That page carries a form built from the category's term set; the seller fills it in and signs with their passkey. Values the seller told their agent may pre-fill it; only what the seller confirms is stored, and the agent learns only that the listing is approved.

TermVisibilityUsed for
floorPrivateThe lowest acceptable price; never disclosed to any agent
available_untilPublicAfter it, the listing is closed to offers
fulfillment_options, payment_termsPublicThe UCP delivery options and payment terms an offer may choose from
release_condition, deliver_within_daysPublicWhen held funds are released, and when a buyer may claim non-delivery

Term sets carry category rules without new protocol: goods.small/1 for everyday goods, vehicles/1 adds deposits and inspections. Constraints come from a closed set (min, max, gt_term, lt_term, lte_list_price, min_ratio_of_list_price), so every marketplace checks terms the same way. The deal record carries a salted terms_commitment: proof of exactly what the seller signed, without revealing it.

3

Offers & Deal Terms

How two agents agree the whole deal: price, delivery and payment.

An offer carries Deal Terms: a price, one UCP fulfillment option and one UCP payment term, each chosen from those the listing allows. Offers and counters share a negotiation_id; a reply names what it replaces in supersedes; every offer has an expires_at. A counter is an invitation, not a commitment: only the seller side accepts, and a buyer agrees to a counter by offering at its terms.

Offer states An offer starts open. It can be countered or escalated to the seller for approval. It ends accepted, declined, expired, superseded or refused. open countered awaiting_approval accepted superseded declined expired refused buyer re-offers approved, then re-check fails
An open offer can also end directly (accepted at tier auto, declined, expired or superseded). An ask on an offer expires no later than the offer. Accepting reserves the listing: a second accept gets listing_reserved.

An accepted offer becomes a single-use checkout signed by the marketplace and bound to the listing, the Deal Terms, the buyer agent's key and a nonce. The listing is reserved for it, and its Deal Terms are fixed: later changes to the listing's terms or price apply to future offers only.

4

The decision

Every agent call gets exactly one answer from the marketplace, in the RCTP-Decision header.

auto · act nowask · act only after the seller approvesforbid · never

The marketplace checks in a fixed order and stops at the first failure: signature and operator → grant (seller side) → listing (the seller's, has terms, open, not reserved) → buyer requirements → terms, Deal Terms and offer budget → tier. Every decision, refusals included, is written to the deal record.

# a buyer offers under the floor: refused, the floor never stated
RCTP-Decision: forbid;action="offer.create";reason=below_floor

# the seller's agent accepts within terms, at tier ask
RCTP-Decision: ask;approval_id="apr_01K8ZB7";expires_in=900;on_timeout=deny

# a buyer probing for the floor runs out of offers
RCTP-Decision: forbid;reason=offer_budget_exhausted;retry_after=3600

An ask that nobody answers is a no. A low offer is refused with below_floor and no private value. An offer budget per buyer agent, with a ceiling per operator, stops anyone binary-searching the floor. Nothing an agent writes, no prompt and no listing text, can change a tier, a term or a grant.

5

Deal record

The signed, hash-chained history of one deal, and the only thing that moves money.

UCP order events say what happened; the deal record says who attests it. RCTP adds four checkpoints UCP lacks (funds_held, accepted, rejected, released) and reuses UCP's fulfillment events and adjustments (shipped, delivered, return, refund). Each event is signed by the party that observed it, first-hand or relayed.

Money moves whenRequires
releasedfunds_held, then the release condition (by default the buyer's accepted)
refund after rejected · not_as_describedA completed, attested return of the item
refund after rejected · not_receivedOnly after deliver_within_days since funds_held

Anything else is refused release_condition_unmet. Entries never record a floor, a name, an address or a phone number. Either party may hand the record to an arbiter in a dispute.

Capabilities & verbs

RCTP declares two standalone UCP capabilities. Neither extends dev.ucp.shopping.checkout: an offer exists before any checkout does, and accepting one produces it.

CapabilityCoversProfile config
dev.rctp.listingListings and their Listing TermsTerm sets enforced
dev.rctp.dealA negotiated trade: offers, acceptance and the checkout it produces, and the deal recordOffer expiry; offer budget; webhook URL (operators)

Verbs read as the story of a deal: listing.* puts an item up, offer.* works toward a price, deal.* runs the agreed trade. A verb's prefix names its capability, and its scope is {capability}:{scope}, as in UCP Identity Linking.

VerbScopeDefaultAllowed
listing.createdev.rctp.listing:createaskask · terms are set at this approval
listing.set_termsdev.rctp.listing:set_termsaskask
listing.repricedev.rctp.listing:repriceautoauto, ask · never below the floor
listing.answer_buyerdev.rctp.listing:answer_buyerautoauto, ask · from structured facts
offer.createBuyer verb: checked against the terms, no tier
offer.counterdev.rctp.deal:offer_counterautoauto, ask · never below the floor
offer.acceptdev.rctp.deal:offer_acceptaskask, auto · never below the floor
deal.commit_to_shipdev.rctp.deal:commit_to_shipaskask, auto
deal.disclose_passportdev.rctp.deal:disclose_passportaskask, auto Item level
deal.accept_depositdev.rctp.deal:accept_depositaskask vehicles
deal.sign_contract, account.updatenoneforbidforbid · fixed, no grant can allow them

Discovery

RCTP adds nothing to UCP discovery. The marketplace's profile at /.well-known/ucp lists the two RCTP capabilities with their config, declares the RCTP scopes and tiers in dev.ucp.common.identity_linking, and publishes its signing keys. Agents name their own profile on every call with UCP-Agent; an operator's profile adds a dev.rctp.operator entry with its legal entity, jurisdiction and incident contact.

{
  "ucp": {
    "version": "2026-08-25",
    "capabilities": {
      "dev.rctp.listing": [{ "version": "2026-11-draft5",
        "config": { "term_sets": ["goods.small/1"] } }],
      "dev.rctp.deal": [{ "version": "2026-11-draft5",
        "config": {
          "offer_expiry": { "default_seconds": 172800, "max_seconds": 604800 },
          "offer_budget": { "per_agent": 3, "per_operator": 10, "window_hours": 24 } } }],
      "dev.ucp.common.identity_linking": [{ "version": "2026-08-25",
        "config": { "scopes": {
          "dev.rctp.deal:offer_accept":  { "default_tier": "ask",  "allowed_tiers": ["ask", "auto"] },
          "dev.rctp.listing:create":     { "default_tier": "ask",  "allowed_tiers": ["ask"] }
          // … one entry per scoped verb
        } } }]
    }
  },
  "keys": [{ "kid": "S1qDUEozf3a-2kEg7jyXV9dikUd_9Wfgc3q3bKGpj1o",
             "kty": "EC", "crv": "P-256", "alg": "ES256", … }]
}

Trimmed from the reference gateway's profile. Key IDs are the key's RFC 7638 thumbprint, which is what binds a grant to the key that signs each call. The expiry and budget numbers are the reference defaults; each marketplace publishes its own.

Life of a deal

  1. Connect. The seller grants an agent its verbs and tiers on the marketplace's consent screen. No prices.
  2. List. The agent calls listing.create; the seller sets the terms on the approval page and signs with their passkey.
  3. Offer. A buyer agent offers on Deal Terms. Below the floor it is refused below_floor; otherwise it reaches the seller agent.
  4. Negotiate. Counters and re-offers, linked by negotiation_id and supersedes, each with an expiry.
  5. Accept. The seller side accepts at its tier; the listing is reserved and the offer becomes a single-use checkout.
  6. Pay. The buyer redeems the checkout; the holder of funds signs funds_held.
  7. Hand over. The seller commits to ship; the carrier signs shipped and delivered.
  8. Confirm. The buyer agent signs accepted, and the holder signs released. Or rejected, a signed return, and a refund.

Fixed rules & invariants

Six rules are fixed. Everything else is an open value named by reverse domain, as in UCP.

FR-1The platform enforces the seller's terms, not the agent
FR-2No answer means no
FR-3Private terms never reach any agent
FR-4Money moves only on signed proof
FR-5Facts about people, never identities
FR-6No custom cryptography

Conformance tests hold implementations to nine invariants, each of which has a test vector that records both the correct result and the plausible wrong one.

INV-1Private terms never leave the platform; a low offer is refused below_floor and carries no private value
INV-2An ask that expires is a decline
INV-3deal.sign_contract and account.update are always forbid
INV-4Only the seller signs approvals
INV-5Only the seller, on a trusted surface, can create or change a grant or terms
INV-6An accepted offer becomes a single-use, business-signed checkout; a listing has at most one live checkout
INV-7A revoked or expired grant fails the next signed call
INV-8No custom cryptography
INV-9No personal data in RCTP objects

Relationship to UCP & AP2

Where UCP or AP2 defines a verb or noun, RCTP uses it.

NeedDefined byRCTP adds
Agent identity, request signingUCP profiles, UCP-Agent, RFC 9421An operator entry; key IDs are thumbprints
The seller's permission for an agentUCP Identity Linking (OAuth 2.0)RCTP scopes, tiers, key binding
Delivery options, payment termsUCP Fulfillment, Payment TermsNothing: Deal Terms pick one of each
Shipping and money eventsUCP order fulfillment events and adjustmentsWho attests each event
WebhooksUCP signed webhooksNothing
Buyer authority, paying into escrowAP2 Checkout and Payment MandatesNothing not yet in v0.2
Price negotiationNot defined (UCP discussions #502, #812)dev.rctp.deal
Private limits, enforcement, signed proofNot definedListing Terms, the decision, the deal record
Facts about people and itemsNot definedPortable credentials next

Out of scope: booking and tracking shipments, moving money, negotiation strategy and pricing, identity-proofing methods, transports. RCTP composes with the standards that cover them.

Namespace & versioning

RCTP lives under dev.rctp.*, governed at rctp.dev, and follows UCP's reverse-domain model: anyone can add a term set, an event type or an attestation type under their own domain (for example example.carrier:picked_up_sealed), and parties that don't recognise it treat it as informative and never let it change a decision. Capabilities carry a draft version, currently 2026-11-draft5, and pin a UCP release (2026-08-25). A breaking change increments the version; a deployment may serve the previous version beside it for at most 90 days.

Status

Draft 0.4 · adopted for v0.2

  • Reference implementation v0.2.0-draft.4: Go gateway, TypeScript and Python SDKs, sandbox, conformance suite
  • Starter profile: Core with goods.small/1, approvals at hosted_embedded, money events
  • 24 Starter test vectors pass against the reference gateway

Next

  • AP2 buyer authority (vector V25)
  • Trust, Identity, Item and Custody levels: portable credentials, Item Passport, verified custody
  • MCP and A2A bindings, following UCP's
  • Draft 1.0: two independent implementations, in different jurisdictions, trading end to end