Skip to content

Demand generation

Your strategy’s Plays run for the month, billed per qualified lead, and every lead and dollar of revenue traced to the Play that sourced it.

Kind
Service
Price
$40 per qualified lead
Your time
75 minutes
Approval
Goes out on its own
Lead.generate
You, to your agent

Deliver 25 qualified leads this month from my Hands-on Plays, $40 each, and show me revenue per Play.

curl -X POST "https://api.sb/leaseline.app/leads/generate?mode=try" \
  -H "Authorization: Bearer $SB_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"goal":"Deliver 25 qualified leads this month from my Hands-on Plays, $40 each, and show me revenue per Play.","budget":{"amount":1000,"currency":"USD"}}'
npx startup-builder do Lead.generate --try --data '{"goal":"Deliver 25 qualified leads this month from my Hands-on Plays, $40 each, and show me revenue per Play.","budget":{"amount":1000,"currency":"USD"}}'
{
  "name": "do",
  "arguments": {
    "mode": "try",
    "code": "return await $.Lead.generate({ goal: 'Deliver 25 qualified leads this month from my Hands-on Plays, $40 each, and show me revenue per Play.', budget: { amount: 1000, currency: 'USD' } })"
  }
}
import { $ } from 'startup-builder'

const result = await $.try.Lead.generate({ goal: 'Deliver 25 qualified leads this month from my Hands-on Plays, $40 each, and show me revenue per Play.', budget: { amount: 1000, currency: 'USD' } })
Response
{
  "mode": "try",
  "stored": false,
  "estimate": "About $30.95 per 25 qualified Leads",
  "bills": "$40 a qualified Lead",
  "sample": {
    "play": "Warm intros",
    "qualified leads": "4",
    "first calls": "4",
    "customers": "2",
    "first-year revenue": "$3,576"
  }
}
Try mode reads, stores nothing and spends nothingAPI referenceIts Nouns

What you get

  • 25 qualified leads · Your strategy’s Plays run for the month, billed per qualified lead, and every lead and dollar of revenue traced to the Play that sourced it. · Lead
  • leads[] · Each qualified lead: the account, the person and title, what they asked for, and the Play that sourced it.
  • byPlay[] · Per Play: leads, first calls, customers and first-year revenue read from Stripe.
  • decisions[] · Each week’s change to the mix, with the readout row that caused it.
  • bill · Accepted leads times the price, up to the target.

Connect once: Gmail, Google Calendar, Stripe. How long: The calendar month, read weekly.

Trigger

It runs when you call it, or on any Trigger you set.

TypeScript
await $.Workflow.create({ verb: 'Lead.generate', trigger: { schedule: 'weekly' } })

Steps

Your agent does these steps, one row per step; each step’s check is part of its row and its price.

StepVerbReturnsPriceApproval
1. Plan each week’s Play mixPlayMix.compileThe week’s Plays, hours and sends, inside your budget and sending limitsAbout 20¢Runs on its own
2. Run warm intros and personal first touchesProspect.reachIntros asked from your own inbox, and cold first touches from the warmed second domainAbout $7.95Goes out on its own
3. Answer buyers’ threadsPost.answerTen threads a week answered as you, every claim sourcedAbout $9.19Goes out on its own
4. List on the directories your buyers readPost.submitEach listing submitted from your approved kit, then checked liveAbout $13.04Goes out on its own
5. Answer every inbound within 5 minutesLead.respondEach inbound answered from your pages, with a call or a trial offeredAbout 42¢Runs on its own
6. Qualify each lead and name its PlayLead.routeFit, title and request checked, and the sourcing Play recorded on the leadAbout 16¢Runs on its own
7. Read each Play every weekPlay.reviewEach Play beside its benchmark: keep, fix or switch, naming the row that firedFreeRuns on its own
8. Read revenue back to each PlayMetric.queryFirst-year revenue per Play, from each paying customer’s first leadFreeRuns on its own

Calls: PlayMix.compile, then Prospect.reach, then Post.answer, then Post.submit, then Lead.respond, then Lead.route, then Play.review, then Metric.query.

About $30.95 per 25 qualified leads, each time it runs, capped at $40.00.

Revenue read back to each Play by month end. Warm intros brought the fewest leads and the most revenue per lead, so next month’s mix moves two hours a week to them.

PlayQualified leadsFirst callsCustomersFirst-year revenue
Warm intros442$3,576
Cold email1191$1,788
Community answers750Free
Directory listings530Free
In all27213$5,364

Planning estimate for the per-Play rows.

Example: give it a goal

Deliver 25 qualified leads this month from my Hands-on Plays, $40 each, and show me revenue per Play.

The plan it shows runs 8 steps, priced before it spends anything; Run it above shows the result it returns.

When something fails

Each failure, and what happens next
WhenThen
A Play falls under its break row two weeks runningIts hours move to the Play the readout ranks next, and the Decision names the row that fired.
The month ends under the targetThe work continues at no charge into the next month; only accepted leads are ever billed.
A paying customer has no sourcing PlayThe revenue reads as unattributed in its own row, never spread across the Plays.

Each step retries three times, then falls through to the next route; one item's failure lands in skipped with its reason, never failing the call. Before a step would cross maxCost it stops and returns what it has, with a resume link. Each step's idempotency key is the call's key plus the step and the item: leaseline-lead-generate-1-<step>-<item>.

What it promises

TermThis Service
DoneA qualified lead: a person at an account that fits, whose title matches, who asked for a call or a trial, with the Play that sourced it recorded.
Counted byLead.qualified
Billed$40 a qualified lead, on acceptance
Target25 qualified leads a month, from the Plays your strategy names.
Accepted whenEach lead is accepted 7 days after it is qualified, unless you disqualify it with a reason.
CreditedAny lead you disqualify within 7 days with a reason.
RemedyContinued work at no charge until the target is met, with hours moved to the Plays that delivered.
EvaluatorCode reads Lead.qualified with its fit, title and sourcing Play, and reads Stripe payments back to each lead.
WindowThe calendar month.
Assurancemeasured, the weakest check on the way to done
Oversightnone: agents do every step

December, Leaseline’s second month on Hands-on, ordered at a target of 25.

CountWhat happened
25Ordered
27Delivered
27Qualified from four Plays: cold email 11, community answers 7, directory listings 5, warm intros 4.
2Disqualified by you within 7 days: one was a competitor, one a student. Credited.
25Accepted and billed, the target met in week four.
25Accepted, billed 25 × $40 = $1,000

Change it

AskCompiles to
Run Launch and search instead, and count signups as leads.Lead.generate
Move every hour from directories to warm intros.PlayMix.compile
Show me revenue per Play for the last 90 days.Metric.query
TypeScript
import { $, Service } from 'startup-builder'

export default Service({
  name: 'lead-generate',
  verb: 'Lead.generate',
  input: { strategy: 'string', icp: 'string', target: 'integer', hours: 'number' },
  maxCost: 40,
  builtFrom: ['Prospect.reach', 'Post.answer', 'Post.submit', 'Lead.respond', 'Lead.route', 'Play.review'],
  oversight: { posture: 'none' },
  contract: {
    done: 'Lead.qualified', accept: { by: 'founder', within: '7d', silence: 'accept' }, assurance: 'measured',
    bills: { usd: 40, per: 'qualified Lead', upTo: 'target' }, target: 25, remedy: 'continue-until-target',
  },
  execute: async (ctx, { strategy, icp, target = 25, hours = 5 }) => {
    while ((await ctx.count('Lead.qualified', { accepted: true })) < target) {
      const mix = await ctx.step('mix', () => $.PlayMix.compile({ strategy, hours, icp }))
      for (const play of mix.plays) await ctx.step(`run:${play.id}`, () => $.Play.apply({ play: play.id, hours: play.hours }))
      await ctx.step('readout', () => $.Play.review({ plays: mix.plays.map((p) => p.id) }))
      await ctx.sleep('1w')
    }
    return ctx.step('revenue', () => $.Metric.query({ metric: 'first-year-revenue', by: 'play', since: 'month' }))
  },
})

Extend it with extends: 'Lead.generate' and base(), or compose your own from these steps.

Works with

Plays that order it: Cold email, Community answers, Directory listings, Launch sites, Warm intros.

Built fromKindIts own price
Personal first touchAgent taskAbout $1.33 per 100 people
Answer threadsAgent taskAbout $2.30 per 10 answers
Directory submissionsWorkflowAbout $13.04 per 40 directories
Answer every inboundAgent taskAbout 1.1¢ an inbound
Inbound routingWorkflowAbout 0.4¢ an inbound
Weekly readoutWorkflowFree

It serves Find your first customers. It deepens Strategy and Demand generation.

For agents

For agents: the guide, its approvals, retries and lookups
FactValue
GuideLead.generate
Guide approvallimits
GoalDeliver 25 qualified leads this month from my Hands-on Plays, $40 each, and show me revenue per Play. It may change counts, the order of steps, soft filters and the route a read takes, and it stops early when the goal is met. It never relaxes your words, raises its own budget, answers its own approval, calls a Play or acts outside your standing approval.
RetryThree times with backoff, then the next route; the same idempotency key never charges, sends or posts twice
Idempotency keyleaseline-lead-generate-1
LookupsA find: input asks unless exactly one record fits
Step
1. Plan each week’s Play mix
2. Run warm intros and personal first touches
3. Answer buyers’ threads
4. List on the directories your buyers read
5. Answer every inbound within 5 minutes
6. Qualify each lead and name its Play
7. Read each Play every week
8. Read revenue back to each Play

The amounts live once, on the hub (approvals).

Who does each step, and how it is checked
StepFunctionDoerCheckerAssuranceInputs
1. Plan each week’s Play mixagenticThe Marketing lead agentCode checks the mix against your hours, budget and the sending rule before anything runsmeasured$0.strategy, $0.hours
2. Run warm intros and personal first touchesagenticThe SDR agentA second model checks every fact in each message against the row before it sendsgraded$1.mix
3. Answer buyers’ threadsagenticThe Content lead agentA second model checks every claim in each answer against your pagesgraded$1.mix
4. List on the directories your buyers readcodeCodeEach listing read back from the directory until it shows, with its link typemeasured$1.mix
5. Answer every inbound within 5 minutesagenticThe SDR agentA Lead.created read-back for every routed reply, timed from arrivalmeasuredinbound
6. Qualify each lead and name its PlaycodeCodeA Lead.qualified read-back carrying the fit, the title and the sourcing Playmeasured$5.leads, $0.icp
7. Read each Play every weekcodeCodeEach Play’s numbers read against its break rowsmeasured$6.leads
8. Read revenue back to each PlaycodeCodeStripe payments read back to each lead and the Play that sourced itmeasured$6.leads

The doer is never the checker, and the weakest assurance on the path is the whole call’s.

Under the hood

Under the hood: the Systems, Nouns and Events it touches
KindWhat it touches
SystemsAnalytics and experiments
NounsPlay Mix, Prospect, Post, Lead, Play, Metric
EventsPlayMix.compiled, Metric.queried

Reference

Inputs, outputs, its Event and its errors
NameTypeDefaultMeaning
strategyStrategyRequiredThe strategy whose Plays run: Hands-on, Paid, Launch and search, Borrowed, or Keep and grow.
icpstringRequiredYour customer sentence; a qualified lead is at an account that matches it.
targetinteger25Qualified leads this month. Fixed when you order; the work continues at no charge until it is met.
hoursnumber5Your hours a week for the calls and the replies only you can write.

Emits Lead.generated. Refuses with max-cost before it spends, and with the Data calls and Accounts groups (refusals).

Contents