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.
| 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:
npx services.dev check --prices8 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% wonAn 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 needs and writes charge.held. A per-unit price counts the list:
→ POST /returns {"service":"transcript","taxpayer":{"name":"Ada Lovelace","email":"signs@example.test"},"tin_last4":"4417","years":[2024,2025],"purpose":"mortgage underwriting","key":"loan-1042"} 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:
→ POST /returns {"service":"annual-return","business":{"name":"Acme Robotics"},"entity":"S corp","jurisdictions":["US","US-CA","US-NY"],"tax_year":"2026","key":"acme-2026"}
{
"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"],
An upgrade and a self-help price are two choices on one offer:
→ POST /store-listing {"app":"a budgeting app for couples","languages":["fr","de"],"key":"listing-1"} 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}→ POST /matters {"service":"provisional-patent","invention":["disclosure.pdf"],"applicant":{"name":"Ada","email":"signs@example.test"},"entity_size":"micro","key":"patent-1"} 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.
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:
→ 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 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 heldusd: 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:
→ POST /deals {"account":{"name":"Northwind Freight"},"value":80000,"offer":"https://seller.example/offer","key":"northwind"} 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:
git diff services/deal.ts && npx services.dev check services/deal.ts --only ai # the AI budget, declared- 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→ GET /owner/deals/job_7Hr8 # the budget ran out mid-deal 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 sellerWhat each step spends on AI across every job, and the alarm when it jumps: AI spend.
Outcomes covers the proof that releases a share, the window that holds it and what reverses it.
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, an outcome price from the mandate to the payout.
| 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 |
| 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 with allowances |
price.self | number | none | The price when the client performs the reserved acts: two prices |
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 |
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 |
price.release | a fact | delivery | What releases the charge: release |
price.lines | { <name>: Line } | none | Pass-through, flat and referral lines: lines and rails |
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 the price is sold with |
| Code | When |
|---|---|
price_unstated | check: a Service has no price |
price_below_cost | check: pay, nested Services and the AI cap add up to more than the price |
upgrade_below_payout | 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 forbids |
Per job, per unit, tiers, self-help and approval run live on Free; subscriptions and outcome prices on Launch.