---
title: "The buy side"
url: /commerce/buy-side
---

# The buy side

> How a Customer's agents spend: one funded budget, mandates that narrow it, a policy that picks sellers by offer card, and one stream of signed receipts.

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](/how-it-works.md#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.

| Family | What it does |
| --- | --- |
| The buyer account | One 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 budget | Funded on Stripe, then split per agent, task and seller; topped up by hand or by a rule; what is left returns when it closes |
| Mandates | The 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 policy | Allowed 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 seller | A [Key](/reference/platform.md#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 presentation | A signed statement of who authorised what, for how much and until when, sent with each call. The seller verifies it without calling the buyer |
| Approvals | A purchase above a threshold, or outside the policy, waits as Pending on the person the policy names |
| The receipt stream | Every seller's signed receipts in one stream: verified on arrival, reconciled against Stripe, and exported to the Customer's books |
| Spend views | Spend by agent, task, seller and Verb, against each budget and mandate |
| Disputes | Opened 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](/how-it-works.md#composition)).

## Lifecycles and states
| Thing | States | What moves it |
| --- | --- | --- |
| A budget | `funded`, `low`, `exhausted`, `closed` | A payment on Stripe funds it; spend draws it down; a top-up rule or a person refills it; closing returns the rest |
| A mandate | `active`, `suspended`, then `exhausted`, `expired` or `revoked` | Its issuer suspends or revokes it; spend and time end it; revoking a link revokes every link below it |
| A purchase | `proposed`, `decided`, `authorised`, `served`, `receipted`, then `reconciled` or `disputed` | The buyer's decision, the seller's gate, the seller's receipt, and Stripe's settlement |
| A seller credential | `active`, `rolled`, `revoked` | Minted on the first purchase; rolled on a schedule; revoked when no mandate names the seller |
| An approval | `requested`, then `granted`, `declined` or `expired` | The 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`](/reference.md#approval_required), and a payment lifts an empty budget with 402 [`payment_required`](/reference.md#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.

| Who | Declares | The platform does |
| --- | --- | --- |
| The Customer | A budget, its mandates, the selection policy and the approvers, in a buyer file or through the portal | Holds the funds on Stripe, signs each presentation, decides each purchase, and refuses with a cure |
| The Customer | Nothing for credentials | Mints a Key per seller on the first purchase, holds it, rolls it, and revokes it with the last mandate |
| You, the seller | Nothing beyond the Offer and terms: every product accepts mandates and the open agent-payment rails | Verifies each presentation, enforces its limits at your gate, and answers with a receipt |
| You, the seller | A mandate required on a Verb that commits money or acts in the Customer's name | Refuses that Verb without one, with the cure |
| Nobody | Reconciliation | Matches 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.

```ts title="buyer.ts"
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.

```http title="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
| Subsystem | What the buy side takes from it | What the buy side gives it |
| --- | --- | --- |
| Definition and compile | A seller's Verbs that require a mandate; the Customer's buyer policy, checked like any file | The policy's checks at deploy: a mandate wider than its parent is refused |
| Identity, access and policy | The mandate chain, the approvers, and the one decision | Budget and seller limits as inputs to that decision |
| Commerce, sell side | The offer card, `quote`, the 402 with a cure, the receipt | Payment inside the call, a verified mandate, and disputes carrying the receipt |
| Model and records | `Budget`, `Mandate`, `Approval` and `Purchase` as records in the buyer's [Namespace](/reference/platform.md#namespace); spend views as projections | Every purchase and receipt, kept with its history and exported whole |
| Data and Sources | A product built on another reads it as a [Source](/patterns/dataset-api.md#how-a-field-is-filled) with a `cost` | Its spend under a mandate of its own, narrowed at every hop |
| Runtime | The gate, durable intents, reconciliation | Each authorised payment as a durable intent, released once; the receipt stream as observed Events |
| Work | A case step that buys from another seller | The purchase's receipt as the step's evidence; an upstream refund into the case's remedy |
| Interfaces and distribution | The portal's mandates and budgets, every product's MCP | A buyer's tools that carry its policy: allowed sellers, prices and remaining budget |
| Trust and operations | The [Verifier](/reference/platform.md#verifier)'s proof, runaway-spend brakes, evidence | Each 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.