---
title: "Prices"
url: https://services.dev/docs/money/prices
captured: [money-prices.txt]
---
# Prices

URL: https://services.dev/docs/money/prices

> Every form a price takes, from $49 a job to nothing on effort and a share at won. Each is one key on Service(), answers an order with its price before anything is held, and writes one line on the ledger.

A price answers what the buyer pays and for what. It is one key, written once, and every surface reads it: the Site's sentence, the 402 OFFER an agent reads before it spends, the customer portal's order form and `check`'s ledger.

## Eight forms

| Form | Written | Charged | The ledger line |
|---|---|---|---|
| Per job | `price: 49` | $49 a job | `+$49.00` |
| Per unit | `{ usd: 12, per: 'years' }` | $12 for each item of a list input | `+$24.00 · 2 × $12.00` |
| Complexity tier | `{ tiers: { simple: 1800, multistate: 3600 }, tier }` | the tier `tier` picks from the order | `+$3,600.00 · multistate` |
| Subscription with allowances | `{ usd: 2400, every: 'year', includes: { question: 12 } }` | once a cycle; past an allowance, the job's own price | `+$2,400.00 a cycle` · `+$0.00` a job inside it |
| Self-help beside professional | `{ usd: 199, self: 79 }` | $79 when the client performs the reserved acts | `+$79.00 · posture self` |
| Approval as an upgrade | `{ usd: 29, approved: 79 }` | $79 when the order asks for a person's approval | `+$79.00 · reviewer $40.00` |
| Share of an outcome | `{ usd: 99, share: '25%', of: 'recovery' }` | $99 at delivery, then the rest of 25% at the outcome | `+$99.00` · `+$201.00 at outcome` |
| Nothing on effort | `{ usd: 0, share: '5%', of: 'closed_value', on: 'won', ai: 40 }` | 5% at `won`, nothing before | `+$0.00` · `+$3,700.00 at won` |

`check --prices` reads every form back from the reference brands' files, one line each, with the ledger it writes:

```bash
npx services.dev check --prices
```

```txt title="magic values: none"
8 price forms, one Service each, from lingua, api.lawyer, apis.tax and api.forsale
  per job       translation               $49                     +$49.00 on delivery
  per unit      transcript                $12 per year            +$12.00 a year, on its receipt
  tier          annual-return             $1,800 or $3,600        +$3,600.00 multistate, when every filing is accepted
  subscription  tax-plan                  $2,400 a year           +$2,400.00 a cycle · each job inside an allowance +$0.00
  self-help     provisional-patent        $199, or $79 yourself   +$79.00 · the practitioner's $150.00 drops out
  approval      store-listing             $29, or $79 approved    +$79.00 · reviewer $40.00
  share         claim-appeal              $99, then 25%           +$99.00 at delivery · +$201.00 at a $1,200 outcome
  outcome only  deal                      5% at won               +$0.00 on effort · +$3,700.00 at won on $74,000 · breaks even at 9.1% won
```

## The price on the order

An order without `max_usd` answers 402 OFFER with the price and the exact next call, and holds nothing. With `max_usd` at or above the price, the order holds it the way its [release](https://services.dev/docs/money/release.md#how-the-money-is-held) needs and writes `charge.held`. A per-unit price counts the list:

```txt
→ POST /returns {"service":"transcript","taxpayer":{"name":"Ada Lovelace","email":"signs@example.test"},"tin_last4":"4417","years":[2024,2025],"purpose":"mortgage underwriting","key":"loan-1042"}
```

```txt title="402 · OFFER · $12 per year of record, $24.00 for 2 years, each year charged on its own receipt. · magic values: none"
  units   years · 2 × $12.00
  holds   $24.00 once you send max_usd · a year the agency can't find is never charged
  next    POST /returns {"service":"transcript",…,"max_usd":24}
```

A tier is picked from the order itself, so the buyer sees which and why before anything is held:

```txt
→ POST /returns {"service":"annual-return","business":{"name":"Acme Robotics"},"entity":"S corp","jurisdictions":["US","US-CA","US-NY"],"tax_year":"2026","key":"acme-2026"}
```

```json title="captured/money-prices.txt · 402 · magic values: none"
{
  "type": "OFFER",
  "object": "offer",
  "service": "annual-return",
  "price": {
    "usd": 3600,
    "tier": "multistate",
    "tiers": { "simple": 1800, "multistate": 3600 },
    "because": "3 jurisdictions",
    "release": "file.accepted",
    "hold": "capture",
    "methods": ["bank", "card"],
    "sentence": "$3,600, multistate: a federal return and 2 states. Paid at the order and held until every filing is accepted."
  },
  "next": {
    "do": "order",
    "service": "annual-return",
    "arguments": { "entity": "S corp", "jurisdictions": ["US", "US-CA", "US-NY"], "tax_year": "2026", "max_usd": 3600, "key": "acme-2026" },
    "http": "POST /returns {\"service\":\"annual-return\"}"
  }
}
```

An upgrade and a self-help price are two choices on one offer:

```txt
→ POST /store-listing {"app":"a budgeting app for couples","languages":["fr","de"],"key":"listing-1"}
```

```txt title="402 · OFFER · $29 for the AI's work, or $79 with a person's approval. · magic values: none"
  choices   approved: false · $29.00 · AI writes and reviews it
            approved: true · $79.00 · a reviewer approves it before you get it
  next      POST /store-listing {…,"max_usd":29} or {…,"approved":true,"max_usd":79}
```

```txt
→ POST /matters {"service":"provisional-patent","invention":["disclosure.pdf"],"applicant":{"name":"Ada","email":"signs@example.test"},"entity_size":"micro","key":"patent-1"}
```

```txt title="402 · OFFER · $199 with a registered practitioner, or $79 if you sign and file it yourself. · magic values: none"
  choices   posture: 'full' · $199.00 · a practitioner signs and files
            posture: 'self' · $79.00 · you sign and file, in your own name
  next      POST /matters {…,"max_usd":199} or {…,"posture":"self","max_usd":79}
```

A job keeps the price it was ordered at. A change to the file prices new orders only.

## Paying the offer

The buyer pays one of three ways, and each answers the same OFFER:

| Who pays | How | What it holds |
|---|---|---|
| A person | the customer portal's checkout | the hold its release needs, on a card or a bank account |
| Your buyer's code | a saved `payment_method` on the order | the same, off-session |
| The buyer's agent | a Stripe shared payment token, `spt_…`, scoped to your brand's account, with `max_usd` and an expiry | never more than the token allows, for your brand only |

A share holds a mandate instead of money: the buyer's consent, in one sentence, to be charged at the end up to `max_usd`. `price.methods` sets whether the checkout takes cards, bank accounts or both, and a price or `max_usd` of $5,000 and up offers the bank account first, where processing costs a few dollars, not a percentage:

```txt
→ POST /deals {…,"max_usd":12000,"payment":{"token":"spt_…","max_usd":12000,"seller":"api.forsale","expires_at":"2027-04-30"}}   # an agent, with a scoped payment token
```

```txt title="201 · job_7Hq5 · deal · working · mandated · up to $12,000.00, charged at won · magic values: none"
  consent   "Harbor Labs authorizes api.forsale to charge up to $12,000.00 when this deal is won, proven by the payment, until 30 Apr 2027."
  method    bank …6789 · a mandate, for an off-session charge · nothing held
```

## Nothing on effort

`usd: 0` with a share charges nothing until the outcome names its end. The OFFER states the buyer's whole cost at each end. The AI still runs on every job, won or lost, so `ai` says what you fund per job; without it `check` fails `ai_unfunded`:

```txt
→ POST /deals {"account":{"name":"Northwind Freight"},"value":80000,"offer":"https://seller.example/offer","key":"northwind"}
```

```txt title="402 · OFFER · Nothing on effort. 5% of the closed value when the deal is won, proven by the payment. · magic values: none"
  ai closes   5% of the closed value, and nothing else
  a closer    15% from $50,000: the 5%, and 10% to the closer, charged to the seller
  meetings    nothing to you: api.forsale pays its setters
  window      held 60 days after the payment · after that, a reversal is yours
  holds       nothing · a saved bank account or card, charged at won up to max_usd
  ai          api.forsale funds $40.00 of AI on the deal, won or lost
  next        POST /deals {…,"max_usd":12000,"payment_method":"pm_…"}
```

`ai` also says what happens when the budget is spent: `'ask'` asks you in the owner console to fund more for that job, `'person'` hands the step to its escalate role, and `'end'` ends the job at its lost end. The buyer is never billed for AI:

```bash
git diff services/deal.ts && npx services.dev check services/deal.ts --only ai   # the AI budget, declared
```

```txt title="magic values: none"
-  price: { usd: 0, share: '5%', of: 'closed_value', on: 'won', ai: 40 },
+  price: { usd: 0, share: '5%', of: 'closed_value', on: 'won', ai: { usd: 40, then: 'person' } },
  ai      $40.00 a deal, won or lost · then person: the step goes to its escalate role
```

```txt
→ GET /owner/deals/job_7Hr8   # the budget ran out mid-deal
```

```txt title="200 · job_7Hr8 · deal · working · AI $40.00 of $40.00 · magic values: none"
  ai        ai.exhausted at meet, round 6 · then person: tsk_7Hs0, the setter's gig, posted at $250
  next      claimed by mbr_7Hs1 · no AI past the budget, and none billed to the seller
```

What each step spends on AI across every job, and the alarm when it jumps: [AI spend](https://services.dev/docs/operate/observe.md#ai-spend).

[Outcomes](https://services.dev/docs/money/outcomes.md) covers the proof that releases a share, the window that holds it and what reverses it.

## What each form leaves you

`check` prints the least a delivered job leaves you: the price, less the AI cap, each person's pay and any coverage. A nested Service counts at its own floor.

| Service | Each job keeps at least | A stopped job costs at most |
|---|---|---|
| Translation, AI alone | $39.20 (80%) | $9.80 |
| Claim Appeal, a share | $79.20 (80%) | $19.80 |
| Translated Summary, nests Translation | $53.40 (68%) | $25.60 |
| Certified Translation, a signer | $81.40 (43%) | $107.60 |
| Store Listing, approved | $23.20 (29%) | $55.80 |
| Interpreted Call, an interpreter | $15.00 (10%) | $135.00 |

The AI spends at most a fifth of a job's price, redos included, so AI alone keeps you at least 80%.

### On an outcome

A price paid only at its end is a bet with stated odds. It breaks even at lost cost ÷ (what a won job leaves + lost cost), and `check` prints that as `odds`:

| Service | A won job leaves | A lost job costs at most | Breaks even at |
|---|---|---|---|
| Deal, closed by AI alone, $30,000 | $1,490.88 | $40.00, its AI | 2.6% won |
| Deal, closed by a closer, $74,000, you fund the setter | $3,388.66 | $340.00 | 9.1% won, about 1 in 11 |
| The same deal, the seller funds the setter | $3,638.66 | $90.00 | 2.4% won, about 1 in 41 |
| Claim Appeal, $99 then 25% | $299.16 on a $1,200 outcome | nothing: $99 at delivery pays its AI | every job pays |

The owner console tracks each Service's live win rate against its break-even, and `price.margin: 'strict'` fails `win_rate_unmet` when the last 30 days of ends won less often.

Worked in: [the sales example's money](https://services.dev/docs/examples/sales/money.md), an outcome price from the mandate to the payout.

## In each app

| App | What it shows |
|---|---|
| Customer portal | The price sentence on the order form, each choice beside its price, the OFFER's total, and the hold or mandate before the buyer confirms |
| Delivery portal | Never the buyer's price: a member sees their own pay on the teaser, set when the Task posts |
| Owner console | Each Service's price, the least each form leaves you, an outcome price's live win rate against its break-even, and the plan a form needs live |

## Every form

| Key | Written | Left out | Does |
|---|---|---|---|
| `price` | `number \| PriceForm` | required | What a job costs: a number is `usd` per job, charged on delivery |
| `price.usd` | `number` | required in an object | The base charge, or the least a share charges |
| `price.per` | the name of a list input | one job | Charges `usd` for each item of that list |
| `price.tiers`, `price.tier` | `{ <tier>: number }`, a function of the job | none | The tier's price, picked from the order |
| `price.every`, `price.includes` | `'month'`, `{ <service>: number }` | none | A [subscription](https://services.dev/docs/money/subscriptions.md) with allowances |
| `price.self` | `number` | none | The price when the client performs the reserved acts: [two prices](https://services.dev/docs/people/self.md) |
| `price.approved`, `price.payout` | `number`, `number \| Pct` | none | A person's approval as an upgrade, and what it pays them |
| `price.share`, `price.of`, `price.on` | `Pct`, a `money` output, an end | none | A share of an outcome, charged at that end: [outcomes](https://services.dev/docs/money/outcomes.md) |
| `price.ai` | `number \| { usd; then: 'ask' \| 'person' \| 'end' }` | a fifth of `usd`, then `'ask'` | The AI budget per job you fund, and what happens at `ai.exhausted` |
| `price.effort` | `'named'` | nothing on effort | Says a `usd: 0` price charges before its end: the OFFER and the Site lead with each effort charge |
| `price.methods` | `('card' \| 'bank')[]` | card, and bank first from $5,000 | Whether the checkout takes cards, bank accounts or both |
| `price.hold` | `'authorization' \| 'capture' \| 'mandate'` | derived by `check` | How the order holds the money: [release](https://services.dev/docs/money/release.md#how-the-money-is-held) |
| `price.release` | a fact | delivery | What releases the charge: [release](https://services.dev/docs/money/release.md) |
| `price.lines` | `{ <name>: Line }` | none | Pass-through, flat and referral lines: [lines and rails](https://services.dev/docs/money/lines-and-rails.md#lines) |
| `price.margin` | `'floor' \| 'strict'` | `'floor'` | `'strict'` fails a price that a decline and a second person leave below cost, and an outcome price whose last 30 days of ends won less often than its break-even |
| `price.within` | `Within` | `'48h'` | The [deadline](https://services.dev/docs/service/within.md) the price is sold with |

## Refusals

| Code | When |
|---|---|
| [`price_unstated`](https://services.dev/docs/reference/check/price_unstated.md) | `check`: a Service has no price |
| [`price_below_cost`](https://services.dev/docs/reference/check/price_below_cost.md) | `check`: pay, nested Services and the AI cap add up to more than the price |
| [`upgrade_below_payout`](https://services.dev/docs/reference/check/upgrade_below_payout.md) | `check`: the approved price adds less than the person's pay |
| `ai_unfunded` | `check`: a price with `usd: 0` and no `ai` budget |
| `effort_charged` | `check`: a `usd: 0` price charges the buyer before its end, and `price.effort` doesn't name it |
| `win_rate_unmet` | `check`, under `margin: 'strict'`: the last 30 days of ends won less often than the break-even |
| `fee_policy` | `check`: a form your brand's [fee policy](https://services.dev/docs/money/pay.md#your-fee-policy) forbids |

Per job, per unit, tiers, self-help and approval run live on [Free](https://services.dev/docs/money/plans.md#free); subscriptions and outcome prices on [Launch](https://services.dev/docs/money/plans.md#launch).

---

- Up: [Money](https://services.dev/docs/money.md)
- Previous: [Money](https://services.dev/docs/money.md)
- Next: [Subscriptions](https://services.dev/docs/money/subscriptions.md)
