Skip to content

The offers/ folder: one file and what it compiles to

What one offers/ file holds, what each key compiles to, and the checks that read it.

One offers/ file is one Offer: its Price, its trial, its checkout and how it is sold. SalesBuilder compiles it, and show traces every key.

offers/pro.mdx
---
price: { amount: 29, currency: USD, per: month }
limit: { units: 200 }
trial: 14d
checkout: self-serve
sale: self-serve
---
Renewal tracking for up to 200 units.
show
$ npx startup-builder show offers/pro.mdx
price     { amount: 29, currency: USD, per: month }  offers/pro.mdx:2
limit     { units: 200 }                             offers/pro.mdx:3
trial     14d                                        offers/pro.mdx:4
checkout  self-serve                                 offers/pro.mdx:5
sale      self-serve                                 offers/pro.mdx:6
owner     SalesBuilder
leaseline.app
leaseline.app/
├── plays/
│   ├── cold-email.mdx
│   ├── warm-intros.mdx
│   ├── signup-interviews.mdx
│   ├── lead-reactivation.mdx
│   └── events-and-webinars.mdx
├── audiences/
│   ├── small-property-managers.mdx
│   ├── lapsed-leads.mdx
│   └── renewal-season.mdx
├── sequences/
│   └── cold-email-thread-founder.mdx
├── funnels/
│   └── signup.mdx
├── workflows/
│   └── outbound.mdx
├── agents/
│   ├── sales/prospector.mdx
│   └── marketing/content-lead.mdx
├── systems/
│   └── sequences.mdx
├── domains/
│   └── leaseline.app.mdx
├── offers/   ← this folder
│   ├── pro.mdx
│   └── team.mdx
├── content/
│   └── webinars/60-day-notices.mdx
├── metrics/
│   ├── q4.mdx
│   └── positive-reply-rate.mdx
└── startups.lock

The file

KeyOn the pageCompiles toChecked by
pricePricethe Offer’s Price, published by POST /{namespace}/offers/{offer}/publishS8
limitLimitthe Offer’s Limit: what an upgrade Play reads—
trialTrialPOST /{namespace}/offers/{offer}/trial for the days given—
checkoutCheckoutwhere the buyer pays: self-serve ends at POST /{namespace}/orders/place—
saleHow it’s soldwho carries the buyer to yes: self-serve, sales-assisted (POST /{namespace}/meetings/book, POST /{namespace}/quotes/{quote}/send, POST /{namespace}/deals/{deal}/win) or enterprise—

Checks

CheckIt holdsWhat dev prints
S8An Experiment that varies an Offer’s Price assigns by market or by time.experiments/pro-price.mdx:3 S8 varies: offers/pro.mdx price, assigned by contact. Assign by market or by time.

Refusals

CodeFix, then the call that clears it
activation-eventDeclare the Offer’s activation Event before the first ask, then publish it. Then POST /{namespace}/offers/{offer}/publish.
bar-capSet the bar at the 15th percentile of your own first months. Then POST /{namespace}/offers/{offer}/publish.
clusterOffer the plain trial; the account keeps every other term. Then POST /{namespace}/offers/{offer}/trial.
contribution-floorRaise the Price or lower the cost until the margin clears its target, then publish again. Then POST /{namespace}/offers/{offer}/publish.
limit-on-offerAdd a Limit to the Offer, then publish it. Then POST /{namespace}/offers/{offer}/publish.
no-resetKeep the close time written at the post’s publish time. Then POST /{namespace}/offers/{offer}/publish.
outcome-eventDeclare the Offer’s delivered-outcome Event, then publish it. Then POST /{namespace}/offers/{offer}/publish.
priceGet the discount approved, or quote at the floor. Then POST /{namespace}/approvals/{approval}/approve.
price-split-by-buyerAssign the Price test by market or by time. Then POST /{namespace}/experiments/{experiment}/start.
price-syncPublish the Offer so the price file and Stripe Prices match. Then POST /{namespace}/offers/{offer}/publish.
sheet-lockPublish a new version; it reaches new Customers only. Then POST /{namespace}/offers/{offer}/publish.
ship-dateSet tranche 1 to ship within 90 days of the post. Then POST /{namespace}/offers/{offer}/publish.

Calls

offers/ compiledMode try
You, to your agent

Publish the Pro Offer and start a trial, as a dry run.

curl -X POST "https://api.sb/leaseline.app/offers/offer_1/publish?mode=try" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"

curl -X POST "https://api.sb/leaseline.app/offers/offer_1/trial?mode=try" \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"customer":"customer_1","days":1}'
import { $ } from 'startup-builder'

await $.Offer.publish({ offer: 'offer_1' }, { mode: 'try' })   // offers/pro.mdx, $29 a month
return await $.Offer.trial({ offer: 'offer_1', customer: 'customer_1', days: 1 }, { mode: 'try' })
npx startup-builder do Offer.publish --json '{"offer":"offer_1"}' --try
npx startup-builder do Offer.trial --json '{"offer":"offer_1","customer":"customer_1","days":1}' --try
{
  "name": "do",
  "arguments": {
    "code": "await $.Offer.publish({ offer: 'offer_1' }, { mode: 'try' })   // offers/pro.mdx, $29 a month\nreturn await $.Offer.trial({ offer: 'offer_1', customer: 'customer_1', days: 1 }, { mode: 'try' })",
    "mode": "try"
  }
}
Response200application/json
{
  "subscription": {
    "$id": "https://api.sb/leaseline.app/subscriptions/subscription_1",
    "$type": "Subscription",
    "status": "active"
  },
  "offer": {
    "$id": "https://api.sb/leaseline.app/offers/offer_1",
    "$type": "Offer",
    "price": {
      "amount": 29,
      "currency": "USD"
    }
  },
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/action_1",
    "operation": "Offer.trial",
    "status": "done"
  }
}
sample
CallWhat it does
POST /{namespace}/offers/{offer}/publishPublish makes an Offer available for parties to accept. Emits Offer.published.
POST /{namespace}/offers/{offer}/trialTrial starts a Customer on an Offer free for a set number of days, with or without a card, converting or ending by its terms. Emits Offer.trialed.
POST /{namespace}/orders/placePlace commits a Customer to buy an Offer once and records the Offer Version and price at that moment. Emits Order.placed.
POST /{namespace}/quotes/{quote}/sendSend presents a drafted Quote to its buyer and freezes its lines, total and payment terms. Emits Quote.sent.

Compiled, not written: edit the records it reads (compile table; cap), then regenerate. Every step runs from a sentence or a line of code. In your words: the CRM words you know, and where each lives here.

Contents