URL: /capabilities/reach-out/booked-first-calls · Id: `page:/capabilities/reach-out/booked-first-calls`

# Booked first calls

> Held first calls with buyers who fit, a budget owner confirmed on each, billed per held meeting against a monthly target you set.

Held first calls with buyers who fit, a budget owner confirmed on each, billed per held meeting against a monthly target you set.

```text title="Run it · Ask"
Deliver 12 held first calls with US property managers this month, $90 each, and show me the plan first.
```

```ts title="Run it · SDK"
import { $ } from 'startup-builder'

const result = await $.try.Meeting.deliver({ goal: 'Deliver 12 held first calls with US property managers this month, $90 each, and show me the plan first.', budget: { amount: 1080, currency: 'USD' } })
```

```json title="Run it · Response"
{
  "mode": "try",
  "stored": false,
  "estimate": "About $28.53 per 12 held meetings",
  "bills": "$90 a held meeting",
  "sample": {
    "account": "Harborview Property Management",
    "person": "Dana W., Director of Operations",
    "budget owner": "confirmed on the call",
    "state": "held, accepted",
    "sourced": "Cold email"
  }
}
```

- **Kind:** Service
- **Price:** $90 per held meeting
- **Your time:** 40 minutes
- **Approval:** You do a step
- **Deepens:** [`capability:demand-generation`](https://startupbuilder.dev/systems/integrations/upstreams#demand-generation)

## What you get
- **12 held meetings** · Held first calls with buyers who fit, a budget owner confirmed on each, billed per held meeting against a monthly target you set. · [`noun:meeting`](https://startupbuilder.dev/business/nouns/meeting)
- `held[]` · Each held meeting: the account, the person and title, the budget owner you confirmed, and the Play that sourced it.
- `credited[]` · No-shows and meetings you disqualified within 48 hours, each with its reason; none is billed.
- `progress` · Held against the target, with the lists, sends and replies behind it.
- `bill` · Accepted meetings times the price: what the month owes.

**Connect once:** [Gmail](/code/integrations/gmail), [Google Calendar](/code/integrations/google-calendar). **How long:** The calendar month; the first calls land in week two, after the first sends.

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

```ts
await $.Workflow.create({ verb: 'Meeting.deliver', 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.

| Step | Verb | Returns | Price | Approval |
| --- | --- | --- | --- | --- |
| 1. Build the month’s lists | [`Audience.build`](/capabilities/find-customers/build-a-verified-list) | About 1,000 checked work emails, each at the right company, none already a contact | About $13.81 | Runs on its own |
| 2. Write and send personal first touches | [`Prospect.reach`](/capabilities/reach-out/personal-first-touch) | A first email to each person whose opening line quotes their own evidence, then two follow-ups | About $13.25 | Goes out on its own |
| 3. Answer every reply within 5 minutes | [`Lead.respond`](/capabilities/convert-visitors/answer-every-inbound) | Each reply answered from your pages, with a call offered to each positive one | About 36¢ | Runs on its own |
| 4. Book the call | [`Meeting.book`](/code/apps/scheduling/book) | A first call at a time both calendars hold free | Free | Runs on its own |
| 5. Brief you before each call | [`Deal.brief`](/capabilities/reach-out/account-brief) | Why they might buy now, the objection to expect and the question that finds the budget owner | About $1.11 | Runs on its own |
| 6. Read who attended | `Collection.query` | Each meeting `held` when both sides joined for 10 minutes or more, else a no-show booked again | Free | Runs on its own |
| 7. You confirm the budget owner on the call | [`Lead.qualify`](/code/apps/crm/qualify) | The title match and the budget owner, recorded on the lead; a meeting you disqualify within 48 hours is credited | Free | You do this step |

Calls: `Audience.build`, then `Prospect.reach`, then `Lead.respond`, then `Meeting.book`, then `Deal.brief`, then `Collection.query`, then `Lead.qualify`.

About $28.53 per 12 held meetings, each time it runs, capped at $40.00.

## Example: give it a goal
> Deliver 12 held first calls with US property managers this month, $90 each, and show me the plan first.

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

## When something fails

| When | Then |
| --- | --- |
| The month ends under the target | The work continues at no charge into the next month until the target is met; only accepted meetings are ever billed. |
| A mailbox nears its bounce threshold | It rests itself and the other inbox carries the day; sends never move to your main domain. |
| A booked meeting is a no-show | It is never billed, and the agent offers the person two new times the same day. |
| You disqualify a meeting after 48 hours | It stays accepted and billed; the reason still trains the next list. |

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-meeting-deliver-1-<step>-<item>`.

## What it promises
| Term | This Service |
| --- | --- |
| Done | A held first call at an account that fits your customer sentence, with a person whose title matches, and a budget owner confirmed on the call. |
| Counted by | `Meeting.held` |
| Billed | $90 a held meeting, on acceptance |
| Target | 12 held meetings a month, fixed when you order. |
| Accepted when | You confirm the budget owner on the call. A meeting you do not disqualify within 48 hours is accepted. |
| Credited | No-shows, and any meeting you disqualify within 48 hours with a reason. |
| Remedy | Continued work at no charge until the target is met: more lists, more first touches and more follow-ups, inside the same sending limits. |
| Evaluator | Code reads `Meeting.held` from the calendar and checks the account and title against your sentence; you confirm the budget owner. |
| Window | The calendar month. A meeting booked in the month and held within 14 days counts toward it. |
| Assurance | `attested`, the weakest check on the way to done |
| Oversight | `performs-step`, because `high-stakes` |

**November, Leaseline’s first full month, ordered at a target of 12.**

| Count | What happened |
| --- | --- |
| 12 | Ordered |
| 10 | Delivered |
| 12 | Booked from 1,000 first emails, 34 replies and 19 positive replies. |
| 2 | No-shows: never held, never billed, and both booked again. |
| 1 | Disqualified by you within 48 hours: the person had no say over the budget. Credited. |
| 3 | Still owed on the target of 12, so the work continues into December at no charge. |
| **9** | **Accepted, billed 9 × $90 = $810** |

## Change it
| Ask | Compiles to |
| --- | --- |
| Count only meetings with an owner or COO. | [`Meeting.deliver`](/capabilities/reach-out/booked-first-calls) |
| Raise the target to 20 next month and add LinkedIn as a second channel. | [`Meeting.deliver`](/capabilities/reach-out/booked-first-calls) |
| Brief me two hours before each call instead of the night before. | [`Deal.brief`](/capabilities/reach-out/account-brief) |

```ts
import { $, Service } from 'startup-builder'

export default Service({
  name: 'meeting-deliver',
  verb: 'Meeting.deliver',
  input: { icp: 'string', titles: 'string[]', target: 'integer', offer: 'string', calendar: 'string', mailboxes: 'string[]' },
  maxCost: 40,
  builtFrom: ['Audience.build', 'Prospect.reach', 'Lead.respond', 'Deal.brief'],
  oversight: { posture: 'performs-step', reason: 'high-stakes' },          // you take the call
  contract: {
    done: 'Meeting.held', accept: { by: 'founder', within: '48h', silence: 'accept' }, assurance: 'attested',
    bills: { usd: 90, per: 'held meeting' }, target: 12, credits: ['no-show', 'disqualified-within-48h'], remedy: 'continue-until-target',
  },
  execute: async (ctx, { icp, titles, target = 12, offer, calendar, mailboxes }) => {
    while ((await ctx.count('Meeting.held', { accepted: true })) < target) {
      const list = await ctx.step('list', () => $.Audience.build({ icp, titles, size: 100, maxCost: 2 }))
      await ctx.step('reach', () => $.Prospect.reach({ audience: list.$id, offer, ask: 'a 20-minute call', mailboxes, maxCost: 3 }))
      await ctx.waitFor('Prospect.reached', { audience: list.$id })                   // replies route to Lead.respond, then Meeting.book
    }
  },
})
```

Extend it with `extends: 'Meeting.deliver'` and `base()`, or [compose your own](/code/compose) from these steps.

## Works with
**Plays that order it:** [Benchmark rows](/plays/benchmark-rows), [Cold email](/plays/cold-email), [LinkedIn outbound](/plays/linkedin-outbound), [Proof-of-work outreach](/plays/proof-of-work-outreach), [Warm intros](/plays/warm-intros).

| Built from | Kind | Its own price |
| --- | --- | --- |
| [Build a verified list](/capabilities/find-customers/build-a-verified-list) | Workflow | About $1.38 per 100 checked emails |
| [Personal first touch](/capabilities/reach-out/personal-first-touch) | Agent task | About $1.33 per 100 people |
| [Answer every inbound](/capabilities/convert-visitors/answer-every-inbound) | Agent task | About 1.1¢ an inbound |
| [Account brief](/capabilities/reach-out/account-brief) | Agent task | About 9.3¢ a brief |

It serves [Reach out](/capabilities/reach-out). It deepens [`process:outbound`](https://startupbuilder.dev/workflows/processes/outbound) and [`capability:demand-generation`](https://startupbuilder.dev/systems/integrations/upstreams#demand-generation).

## For agents

| Fact | Value |
| --- | --- |
| Guide | `Meeting.deliver` |
| Guide approval | `ask` |
| Goal | Deliver 12 held first calls with US property managers this month, $90 each, and show me the plan first. 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. |
| Retry | Three times with backoff, then the next route; the same idempotency key never charges, sends or posts twice |
| Idempotency key | `leaseline-meeting-deliver-1` |
| Lookups | A `find:` input asks unless exactly one record fits |

| Step | Action class | Seat rule that would hold it |
| --- | --- | --- |
| 1. Build the month’s lists | None | None. |
| 2. Write and send personal first touches | None | None. |
| 3. Answer every reply within 5 minutes | None | None. |
| 4. Book the call | None | None. |
| 5. Brief you before each call | None | None. |
| 6. Read who attended | None | None. |
| 7. You confirm the budget owner on the call | None | None. |

The amounts live once, on the hub ([approvals](https://startupbuilder.dev/agents/approvals)).

| Step | Function | Doer | Checker | Assurance | Inputs |
| --- | --- | --- | --- | --- | --- |
| 1. Build the month’s lists | `code` | Code | Code reads each address’s check result and its domain against the account’s own before the row joins | `measured` | `$0.icp, $0.titles` |
| 2. Write and send personal first touches | `agentic` | The [SDR](/capabilities/agents/sdr) agent | A second model checks every fact in each message against the row before it sends | `graded` | `$1.audiences, $0.offer, $0.mailboxes` |
| 3. Answer every reply within 5 minutes | `agentic` | The [SDR](/capabilities/agents/sdr) agent | A `Lead.created` read-back for every routed reply, timed from the reply | `measured` | `$2.replies` |
| 4. Book the call | `code` | Code | A `Meeting.booked` read-back from both calendars | `measured` | `$3.positive, $0.calendar` |
| 5. Brief you before each call | `agentic` | The [AE](/capabilities/agents/ae) agent | A second model checks each fact in the brief against its source | `graded` | `$4.meetings` |
| 6. Read who attended | `code` | Code | The calendar’s attendance and the conference join log, read 15 minutes after the slot | `measured` | `$4.meetings` |
| 7. You confirm the budget owner on the call | `human` | You | Code reads your qualification back onto the lead; silence for 48 hours accepts the meeting | `attested` | `$6.held` |

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

## Under the hood

| Kind | What it touches |
| --- | --- |
| Systems | [CRM](/code/apps/crm), [Scheduling](/code/apps/scheduling) |
| Nouns | [`noun:audience`](https://startupbuilder.dev/business/nouns/audience), [`noun:prospect`](https://startupbuilder.dev/business/nouns/prospect), [`noun:lead`](https://startupbuilder.dev/business/nouns/lead), [`noun:meeting`](https://startupbuilder.dev/business/nouns/meeting), [`noun:deal`](https://startupbuilder.dev/business/nouns/deal), [`noun:collection`](https://startupbuilder.dev/business/nouns/collection) |
| Events | `Meeting.booked`, `Collection.queried`, `Lead.qualified` |

## Reference

| Name | Type | Default | Meaning |
| --- | --- | --- | --- |
| `icp` | `string` | Required | Your customer sentence. Every meeting is at an account that matches it. |
| `titles` | `string[]` | Required | The buyer titles that count, in the buyer’s own words. |
| `target` | `integer` | `12` | Held meetings this month. Fixed when you order; the work continues at no charge until it is met. |
| `offer` | `Offer` | Required | What the first touches offer; no message claims what it cannot do. |
| `calendar` | `Calendar` | `your connected calendar` | Where the calls are booked, in the hours you set. |
| `mailboxes` | `Mailbox[]` | `your two warmed inboxes` | Cold first touches send from 2 inboxes on a warmed second domain, such as tryleaseline.app, 25 a day each after a 14-day ramp. |

Emits `Meeting.delivered`. Refuses with [`max-cost`](/code/refusals#max-cost) before it spends, and with the Data calls and Accounts groups ([refusals](/code/refusals)).