Skip to content

The buy side

The buy side lets a Customer's agents spend money for it. A person funds one budget, mandates narrow it per agent, task and seller, and every purchase comes back as a signed receipt in one stream.

Capability families

The buy side is Commerce seen from the other end: the same offer card, the same 402 with a cure, the same receipt. One decision governs both ends, so a refusal reads alike whichever side makes it.

FamilyWhat it does
The buyer accountOne per Customer org: its budget, its agents and the people who answer for them, its policy and its receipts. A person opens it; agents spend from it
The budgetFunded on Stripe, then split per agent, task and seller; topped up by hand or by a rule; what is left returns when it closes
MandatesThe link from a person to an agent: scoped to sellers and Verbs, budgeted, time-boxed and revocable. A sub-mandate narrows its parent; a standing mandate covers recurring spend
The selection policyAllowed and blocked sellers, the most to pay per unit, the outside proof a seller must show, and the terms it must offer. It ranks offer cards before any call
A credential per sellerA Key for each seller, minted on the first purchase and held by the buy side. The agent never sees it, and it never enters a prompt
Mandate presentationA signed statement of who authorised what, for how much and until when, sent with each call. The seller verifies it without calling the buyer
ApprovalsA purchase above a threshold, or outside the policy, waits as Pending on the person the policy names
The receipt streamEvery seller's signed receipts in one stream: verified on arrival, reconciled against Stripe, and exported to the Customer's books
Spend viewsSpend by agent, task, seller and Verb, against each budget and mandate
DisputesOpened from the stream with the receipt; a refund returns to the budget it came from

A product is a buyer too. When it calls a product it is built on, it spends under a mandate of its own, and the mandate narrows at every hop (composition).

Lifecycles and states

ThingStatesWhat moves it
A budgetfunded, low, exhausted, closedA payment on Stripe funds it; spend draws it down; a top-up rule or a person refills it; closing returns the rest
A mandateactive, suspended, then exhausted, expired or revokedIts issuer suspends or revokes it; spend and time end it; revoking a link revokes every link below it
A purchaseproposed, decided, authorised, served, receipted, then reconciled or disputedThe buyer's decision, the seller's gate, the seller's receipt, and Stripe's settlement
A seller credentialactive, rolled, revokedMinted on the first purchase; rolled on a schedule; revoked when no mandate names the seller
An approvalrequested, then granted, declined or expiredThe approver the policy names; a grant resumes the purchase once

Each move is a Verb and writes its Event: Mandate.revoked, Approval.granted, Budget.exhausted, Receipt.reconciled.

The decision for one purchase

Before an agent's call leaves, the buy side asks the questions below in order. The first that fails answers, and nothing is spent.

  1. The mandate is active, in time, and names the seller and the Verb.
  2. The policy allows the seller.
  3. The seller's offer card meets the policy: price per unit, proof and terms.
  4. The quote fits under the call's Max-Cost, the task's budget, the agent's and the seller's.
  5. The price is under the approval threshold; else the purchase waits on a person.
  6. The budget holds the funds; else a top-up is the cure.

A refusal's status follows what lifts it, on this side too. A person lifts a threshold with 403 approval_required, and a payment lifts an empty budget with 402 payment_required. The seller's own gate then runs its checks as for any call, and checks the presentation's limits too.

What you declare, what the platform does

The buy side has two authors: the Customer who spends, and you, the seller.

WhoDeclaresThe platform does
The CustomerA budget, its mandates, the selection policy and the approvers, in a buyer file or through the portalHolds the funds on Stripe, signs each presentation, decides each purchase, and refuses with a cure
The CustomerNothing for credentialsMints a Key per seller on the first purchase, holds it, rolls it, and revokes it with the last mandate
You, the sellerNothing beyond the Offer and terms: every product accepts mandates and the open agent-payment railsVerifies each presentation, enforces its limits at your gate, and answers with a receipt
You, the sellerA mandate required on a Verb that commits money or acts in the Customer's nameRefuses that Verb without one, with the cure
NobodyReconciliationMatches every receipt to its payment on Stripe, flags any mismatch, and exports the stream

Example

A finance lead gives Acme's research agents 200 USD a month across three sellers. The agent alone may spend 150, at most 20 on one task, and a person approves any purchase above 2.

buyer.ts
19 lines
import { define, mandate } from 'apis.dev'

/** Acme's research agents: 200 USD a month, spent only where price and proof clear the bar. */
export default define({
  name: 'acme-research', domain: 'acme.com',
  …
  buy: {
    budget:  { month: 200 },                              // funded on Stripe
    sellers: {
      'companyfacts.apis.dev': { month: 50 },
      'summaries.apis.dev':    { month: 100 },
      'meetings.apis.dev':     { month: 50 },
    },
    choose:  { verified: true, success: 0.99,             // the Verifier's proof
               price: { 'Company.get': 0.003 } },         // the most per unit
    approve: { above: 2, role: 'finance' },               // a person past 2 a purchase
    researcher: mandate({ month: 150, task: 20, for: '90d' }),
  },
})

The researcher asks for Company.verify, a person's check at 5. The seller's gate reads the mandate's threshold and answers with the cure.

Response
HTTP/1.1 403 Forbidden
Content-Type: application/problem+json
X-Cost: price=0, currency="USD"
X-Request-Id: req_5b0e2c7d91a4f36e8d27

{
  "type": "https://summaries.apis.dev/docs/errors#approval_required",
  "title": "Forbidden",
  "status": 403,
  "detail": "Company.verify costs 5; the mandate approves up to 2 alone.",
  "code": "approval_required",
  "approval": "https://summaries.apis.dev/approvals/apr_1",
  "mandate": ["dana@acme.com", "org_acme", "researcher"],
  "instance": "req_5b0e2c7d91a4f36e8d27"
}

The approval also lands in Acme's one queue. Once a finance member grants it, the same call runs once and its receipt joins the stream.

Contracts with the other subsystems

SubsystemWhat the buy side takes from itWhat the buy side gives it
Definition and compileA seller's Verbs that require a mandate; the Customer's buyer policy, checked like any fileThe policy's checks at deploy: a mandate wider than its parent is refused
Identity, access and policyThe mandate chain, the approvers, and the one decisionBudget and seller limits as inputs to that decision
Commerce, sell sideThe offer card, quote, the 402 with a cure, the receiptPayment inside the call, a verified mandate, and disputes carrying the receipt
Model and recordsBudget, Mandate, Approval and Purchase as records in the buyer's Namespace; spend views as projectionsEvery purchase and receipt, kept with its history and exported whole
Data and SourcesA product built on another reads it as a Source with a costIts spend under a mandate of its own, narrowed at every hop
RuntimeThe gate, durable intents, reconciliationEach authorised payment as a durable intent, released once; the receipt stream as observed Events
WorkA case step that buys from another sellerThe purchase's receipt as the step's evidence; an upstream refund into the case's remedy
Interfaces and distributionThe portal's mandates and budgets, every product's MCPA buyer's tools that carry its policy: allowed sellers, prices and remaining budget
Trust and operationsThe Verifier's proof, runaway-spend brakes, evidenceEach purchase's decision, kept as evidence; a tripped brake as an Event

The seam. A Customer's books read the stream through the export and Events, and never write it.

What Customers and their agents meet

  • A finance lead. One budget, one approval queue and one statement across every seller. They fund on Stripe, set the policy, revoke a mandate in one move, and export the stream to their books.
  • An agent. Its tools show which sellers it may use, what each costs and what is left. It buys with no sign-up, carries no secret, and relays a refusal's cure to its person.
  • An engineer. Spend by agent, task and seller, each line beside the receipt it came from, through the API, the CLI and MCP.
  • A seller. A verified mandate on each call, a Key it never minted by hand, and payment at its printed price.
  • Anyone disputing. A wrong answer is disputed from the stream with its receipt; the refund returns to the budget it came from.

Buyer and seller meet on one contract: the offer card before the call, the 402 with a cure during it, the signed receipt after.