Prices

The running jobjob_7Hq2 · accepted · document.fr-CA.pdf · $49.00 final

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.

FormWrittenChargedThe ledger line
Per jobprice: 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:

Run
npx services.dev check --prices
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

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 needs and writes charge.held. A per-unit price counts the list:

Call
→ POST /returns {"service":"transcript","taxpayer":{"name":"Ada Lovelace","email":"signs@example.test"},"tin_last4":"4417","years":[2024,2025],"purpose":"mortgage underwriting","key":"loan-1042"}
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:

captured/money-prices.txt · 402 · magic values: none
→ 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:

Call
→ POST /store-listing {"app":"a budgeting app for couples","languages":["fr","de"],"key":"listing-1"}
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}
Call
→ POST /matters {"service":"provisional-patent","invention":["disclosure.pdf"],"applicant":{"name":"Ada","email":"signs@example.test"},"entity_size":"micro","key":"patent-1"}
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.

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

Who paysHowWhat it holds
A personthe customer portal's checkoutthe hold its release needs, on a card or a bank account
Your buyer's codea saved payment_method on the orderthe same, off-session
The buyer's agenta Stripe shared payment token, spt_…, scoped to your brand's account, with max_usd and an expirynever 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:

Call
→ 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
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

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:

Call
→ POST /deals {"account":{"name":"Northwind Freight"},"value":80000,"offer":"https://seller.example/offer","key":"northwind"}
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:

Run
git diff services/deal.ts && npx services.dev check services/deal.ts --only ai   # the AI budget, declared
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
Call
→ GET /owner/deals/job_7Hr8   # the budget ran out mid-deal
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.

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.

ServiceEach job keeps at leastA 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:

ServiceA won job leavesA lost job costs at mostBreaks even at
Deal, closed by AI alone, $30,000$1,490.88$40.00, its AI2.6% won
Deal, closed by a closer, $74,000, you fund the setter$3,388.66$340.009.1% won, about 1 in 11
The same deal, the seller funds the setter$3,638.66$90.002.4% won, about 1 in 41
Claim Appeal, $99 then 25%$299.16 on a $1,200 outcomenothing: $99 at delivery pays its AIevery 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.

AppWhat it shows
Customer portalThe 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 portalNever the buyer's price: a member sees their own pay on the teaser, set when the Task posts
Owner consoleEach 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
KeyWrittenLeft outDoes
pricenumber | PriceFormrequiredWhat a job costs: a number is usd per job, charged on delivery
price.usdnumberrequired in an objectThe base charge, or the least a share charges
price.perthe name of a list inputone jobCharges usd for each item of that list
price.tiers, price.tier{ <tier>: number }, a function of the jobnoneThe tier's price, picked from the order
price.every, price.includes'month', { <service>: number }noneA subscription with allowances
price.selfnumbernoneThe price when the client performs the reserved acts: two prices
price.approved, price.payoutnumber, number | PctnoneA person's approval as an upgrade, and what it pays them
price.share, price.of, price.onPct, a money output, an endnoneA share of an outcome, charged at that end: outcomes
price.ainumber | { 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 effortSays 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,000Whether the checkout takes cards, bank accounts or both
price.hold'authorization' | 'capture' | 'mandate'derived by checkHow the order holds the money: release
price.releasea factdeliveryWhat releases the charge: release
price.lines{ <name>: Line }nonePass-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.withinWithin'48h'The deadline the price is sold with
CodeWhen
price_unstatedcheck: a Service has no price
price_below_costcheck: pay, nested Services and the AI cap add up to more than the price
upgrade_below_payoutcheck: the approved price adds less than the person's pay
ai_unfundedcheck: a price with usd: 0 and no ai budget
effort_chargedcheck: a usd: 0 price charges the buyer before its end, and price.effort doesn't name it
win_rate_unmetcheck, under margin: 'strict': the last 30 days of ends won less often than the break-even
fee_policycheck: 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.