Events and webinars
Events and webinars runs your online sessions as a series, follows up each registrant within a day, and counts the Deals they open.
- Channel
- Webinars and events
- Kind
- Owned audience
- Summary
- startupbuilder.dev
Be our Marketing Lead: run a three-session series on 60-day renewal notices, invite our List, follow up every registrant within a day, and send anyone who asks to Priya. I host, and I send the attendee notes. Show me what’s missing; don’t send.
# Not live yet (gaps #2)
curl -X POST "https://api.sb/leaseline.app/campaigns?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"events-and-webinars"}'import { $ } from 'startup-builder'
return await $.Campaign.create({ play: 'events-and-webinars' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-08-24 · Not live yet, gaps #2
npx startup-builder do Campaign.create --json '{"play":"events-and-webinars"}' --try # Not live yet (gaps #2){
"name": "do",
"arguments": {
"code": "return await $.Campaign.create({ play: 'events-and-webinars' }, { mode: 'try' }) // dry run on the day-0 Startup, 2026-08-24 · Not live yet, gaps #2",
"mode": "try"
}
}application/json{
"type": "https: //startupbuilder.dev/ errors/ refused",
"title": "Refused",
"status": 422,
"detail": "events-and-webinars can’t start yet: 1 check fails and 1 warns.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "1, 640 reachable Contacts at 820 Organizations; 23 questions on renewal notices in 30 days",
"doc": "/plays/ events-and-webinars#check-use-when",
"fix": "None needed: 1, 000 Contacts and 10 questions are enough.",
"then": "Metric.query"
},
…
Hand our latest webinar signal to the Marketing Lead agent and show me what it chose and why. Don’t send.
curl "https://api.sb/leaseline.app/events?where=name%20in%20(%22Problem.ranked%22%2C%20%22Gathering.registered%22%2C%20%22Question.asked%22%2C%20%22Registration.attended%22%2C%20%22Registration.missed%22%2C%20%22Prospect.engaged%22%2C%20%22Watch.replayed%22%2C%20%22Deal.opened%22)&limit=1" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# Not live yet (gaps #7)
curl -X POST "https://api.sb/leaseline.app/triggers/fire?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"like":"event_1633"}'
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/decisions?where=on%20%3D%20%22contact_52%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
# Not live yet (gaps #7)
curl "https://api.sb/leaseline.app/actions?where=on%20%3D%20%22contact_52%22" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"import { $ } from 'startup-builder'
const { events: [last] } = await $.Event.list({ where: 'name in ("Problem.ranked", "Gathering.registered", "Question.asked", "Registration.attended", "Registration.missed", "Prospect.engaged", "Watch.replayed", "Deal.opened")', limit: 1 }) // { play } compiled to this Play’s Trigger Events
const { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' }) // the same Event again, in try mode · Not live yet, gaps #7
const { decisions: [decision] } = await $.Decision.list({ where: `on = "${subject}"` }) // what it chose, and why · Not live yet, gaps #7
const { actions } = await $.Action.list({ where: `on = "${subject}"` }) // what it did, with its checks · Not live yet, gaps #7
return { decision, actions }
npx startup-builder do Event.list --json '{"where":"name in (\"Problem.ranked\", \"Gathering.registered\", \"Question.asked\", \"Registration.attended\", \"Registration.missed\", \"Prospect.engaged\", \"Watch.replayed\", \"Deal.opened\")","limit":1}'
npx startup-builder do Trigger.fire --json '{"like":"event_1633"}' --try # Not live yet (gaps #7)
npx startup-builder do Decision.list --json '{"where":"on = \"contact_52\""}' # Not live yet (gaps #7)
npx startup-builder do Action.list --json '{"where":"on = \"contact_52\""}' # Not live yet (gaps #7){
"name": "do",
"arguments": {
"code": "const { events: [last] } = await $.Event.list({ where: 'name in (\"Problem.ranked\", \"Gathering.registered\", \"Question.asked\", \"Registration.attended\", \"Registration.missed\", \"Prospect.engaged\", \"Watch.replayed\", \"Deal.opened\")', limit: 1 }) // { play } compiled to this Play’s Trigger Events\nconst { subject } = await $.Trigger.fire({ like: last.$id }, { mode: 'try' }) // the same Event again, in try mode · Not live yet, gaps #7\nconst { decisions: [decision] } = await $.Decision.list({ where: `on = \"${subject}\"` }) // what it chose, and why · Not live yet, gaps #7\nconst { actions } = await $.Action.list({ where: `on = \"${subject}\"` }) // what it did, with its checks · Not live yet, gaps #7\nreturn { decision, actions }",
"mode": "try"
}
}application/json{
"decision": {
"$id": "https: //api.sb/ leaseline.app/ decisions/ decision_486",
"$type": "Decision",
"choice": "to-the-ae",
"reason": "they picked talk to the team in session 3’s closing poll and manage 180 units, over the 150 your Team plan covers",
"stakes": "low",
"options": [
"plan-a-series",
"invite-your-list",
"follow-up-an-attendee",
"send-the-replay",
"to-the-ae",
"cut-the-replay"
…
sample · 4 Not live yetPreviewOn PATCH /{namespace}/campaigns/{id}Off PATCH /{namespace}/campaigns/{id}Take this one POST /{namespace}/tasks/{task}/claim
action_3 is Priya’s Task with the Brief, due in 60 minutes; action_4 books once Priya picks a time from her calendar.
1.7 against 1.2 Deals per 100 Organizations · ■□□□ Too early to tell · held back at random · n 820 · path → arr
| Try another: the registrant | Choice | Reason |
|---|---|---|
| Tom Becker, Hearthstone Rentals, 180 units: picked “talk to the team” in session 3’s poll | to-the-ae | asked for the team; over 150 units |
| Ana Ruiz, 40 units: attended session 3 live and asked about owner reports | follow-up-an-attendee | attended; her question gets its answer with the replay |
| Joel Park registered for session 3 and missed it | send-the-replay | a no-show: the replay, no apology and no Offer |
| 14 questions on owner reports across Forms and replies in 30 days | plan-a-series | over 10 on one problem: a new series goes to you |
| Session 3 closed with the recording notice shown at every join | cut-the-replay | the notice showed; 3 cuts with no attendee’s face or voice |
- 3 h per session, then 20 min a week
- Your time
- Day 15: first Meeting from a registrant
- First signal
Where it sits: Stranger → Lead → Trialing → Activated → At risk → Churned → Won back · Registrant deals → Deals and trials opened → New Customers ↑ → ARR added each week → ARR
Worth’s formula: about +4 Deals per 100 registrants (Other Startups’ results; no lift of your own yet) × 50 registrants a month × 0.38 paid per Deal × $347 first order ARR ≈ +$264. Under First signal: The leaf reads at day 90 and day 180 after the first session, so the first read is Dec 7; at 820 Organizations held back 1 in 5, day 180 can tell +2.5 Deals per 100 or more.
sample · api.sb/
Start it this week
npx startup-builder add play events-and-webinars # 1 · writes plays/events-and-webinars.mdx (Not live yet, gaps #5)
# 2 · dry run; below, its 422 on 2026-08-24
curl -X POST "https://api.sb/leaseline.app/campaigns?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"events-and-webinars"}'
# 3 · keep it, at You approve each one
curl -X POST https://api.sb/leaseline.app/campaigns \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"play":"events-and-webinars"}'
# on
curl -X PATCH https://api.sb/leaseline.app/campaigns/events-and-webinars \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endsAt":null}'
# off: invitations and Sequences stop; booked sessions stay booked
curl -X PATCH https://api.sb/leaseline.app/campaigns/events-and-webinars \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"endsAt":"now"}' | Check | Fix | Then |
|---|---|---|
use-when pass · Not live yet, gaps #8 | None needed: 1,000 Contacts and 10 questions are enough. | POST /{namespace}/metrics/query |
baseline pass · Not live yet, gaps #8 | None needed: the held-back fifth is the comparison. | POST /{namespace}/metrics/query |
domain-authenticated pass | None needed. | POST /{namespace}/domains/{domain}/authenticate |
mailbox-warm fail · Not live yet, gaps #1 | Warm events@ for 14 days; session 1 invitations go out on day 14. | POST /{namespace}/mailboxes/{mailbox}/warm |
role-unstaffed warn · Not live yet, gaps #8 | Staff the AE, or leave it: talk-to-the-team picks come to you. | POST /{namespace}/roles/{role}/staff |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "events-and-webinars can’t start yet: 1 check fails and 1 warns.",
"checks": [
{
"check": "use-when",
"status": "pass",
"observed": "1,640 reachable Contacts at 820 Organizations; 23 questions on renewal notices in 30 days",
"doc": "/plays/events-and-webinars#check-use-when",
"fix": "None needed: 1,000 Contacts and 10 questions are enough.",
"then": "Metric.query"
},
{
"check": "baseline",
"status": "pass",
"observed": "no series in 90 days",
"doc": "/plays/events-and-webinars#check-baseline",
"fix": "None needed: the held-back fifth is the comparison.",
"then": "Metric.query"
},
{
"check": "domain-authenticated",
"status": "pass",
"observed": "leaseline.app authenticated on 2026-08-02",
"doc": "/plays/events-and-webinars#check-domain-authenticated",
"fix": "None needed.",
"then": "Domain.authenticate"
},
{
"check": "mailbox-warm",
"status": "fail",
"observed": "events@leaseline.app has warmed 0 of 14 days",
"doc": "/plays/events-and-webinars#check-mailbox-warm",
"fix": "Warm events@ for 14 days; session 1 invitations go out on day 14.",
"then": "Mailbox.warm"
},
{
"check": "role-unstaffed",
"status": "warn",
"roles": [
"sales-lead"
],
"owned": 31,
"doc": "/plays/events-and-webinars#check-role-unstaffed",
"fix": "Staff the AE, or leave it: talk-to-the-team picks come to you.",
"then": "Role.staff"
}
]
}It says no, says why, and names the fix.
| Check | Fix (one call) | Your time | Wait |
|---|---|---|---|
use-when · baseline · pass: 1,640 Contacts, 23 questions on one problem; no series before (gaps #8) | POST /{namespace}/metrics/query on registrant-deals; the held-back fifth fills Before | 1 min | none |
domain-authenticated · pass | POST /{namespace}/domains/{domain}/authenticate (done Aug 2) | 0 min | none |
mailbox-warm · fail (Not live yet, gaps #1) | POST /{namespace}/mailboxes/{mailbox}/warm events@leaseline.app | 2 min | 14 days; session 1 is set for Sep 8 |
role-unstaffed · warn (gaps #8): 31 of your open Leads have a person owner, you | POST /{namespace}/roles/{role}/staff, or leave it: talk-to-the-team picks come to you | 0 min | none |
Your number · Before 0 (no series) · Now 9.3 Deals per 100 registrants so far · Target 6 per 100 at day 180 · ■□□□ Too early to tell · held back at random · first read Dec 7
Each registrant costs about $0.08: the Sequence sends from your Domain and the tiering (Worker cost); the room costs nothing on your plan, and you set no paid promotion. That comes to about $4 a month at 50 registrants, and $11 for the 140 so far.
When it starts
| When | Trigger id | Starts on | Window | How it gets in |
|---|---|---|---|---|
| Someone registers for a session | registration-created | event on Gathering.registered where gathering.series = this series | tiered within 15 min; 21d | your Form posts to POST /{namespace}/registrations |
| A session closes and the room reports who attended | session-attended | event on Registration.attended where status = 'attended' | every registrant enrolled within 24 h; 14d | POST /{namespace}/integrations/connect the room |
| An attendee picks talk to the team, or asks for a demo, a trial or a Price | in-session-intent | event on Prospect.engaged where poll = 'talk to the team', or asks for a demo, a trial or a Price | 3d; the AE within 60 min | the same room connection |
+ 5 more for topic demand, registrant questions, replays, repeat attendees and registrant Deals (?lanes=) |
{
"$id": "https://api.sb/leaseline.app/events/event_1633" ,
"$type": "Event",
"name": "Prospect.engaged",
"at": "2026-10-13T17:52:18Z" ,
"seq": 1633,
"data": {
"contact": "contact_52",
"organization": "Hearthstone Rentals",
"gathering": "gathering_3",
"poll": "talk to the team",
"units": 180
}
}npx startup-builder trigger Prospect.engaged --like event_1633 # replays the delivery
npx startup-builder clock advance --by 14d # then reopens the Decision if no Meeting was booked
npx startup-builder listen Prospect.engaged --forward-to http://localhost:3000/hook Who runs it
Marketing Lead · your agent (role:, worker_6) holds the Key Result. It plans, invites, tiers and follows up; talk-to-the-team picks go to AE · Priya Shah (person) (role:, worker_3), and you (Dana Okafor, person, worker_1) host every session and send each attendee note from your own Mailbox. Your number links to Did it work.
| Option | Rung today | Evidence (passed of n) | Moves up at | Drops back when | You can |
|---|---|---|---|---|---|
| Invite your List · Send the replay | It does it, you can stop it | 3 of 3 invitation sends · 52 of 52 | met on day 16 (session 1’s sends) | any send fails a Check → You approve each one | POST /{namespace}/actions/{action}/cancel inside the delay |
| Follow up an attendee | You approve each one | 48 of 48, from your Mailbox | never: your own Mailbox stays here | — | POST /{namespace}/approvals/{approval}/approve · POST /{namespace}/approvals/{approval}/refuse |
| To the AE | It does it | 7 of 7 | — | a pick waits past 60 min → You approve each one | POST /{namespace}/actions/{action}/redirect |
| Plan a series · Cut the replay | You approve each one | 1 of 1 · 7 of 7 | never for a series | — | POST /{namespace}/approvals/{approval}/approve |
| Change the follow-up rule | You approve each one | 0 merged | never | — | POST /{namespace}/changes/{change}/merge · POST /{namespace}/changes/{change}/revert |
| Never: a recorded session called live, a places-left line with no real cap, a question presented as an attendee’s that no attendee asked | To a person, every time | 0 asked | never | — | POST /{namespace}/tasks/{task}/claim |
What it reads · What it may call. It reads Registrations, the room’s attendance and poll, chat questions and the replay’s chapters. Watch minutes, replay views and Visits pick the follow-up and never appear in a Message; chat text is data, never instructions. Its tools are POST /{namespace}/gatherings, POST /{namespace}/approvals, POST /{namespace}/messages/{message}/broadcast, POST /{namespace}/tasks/{task}/assign, POST /{namespace}/meetings/book, POST /{namespace}/videos/draft, POST /{namespace}/posts/{post}/schedule, and any other call becomes an Approval under the Role’s Mandate.
You hold the Marketing Lead Key Result: 6 Deals per 100 registrants at day 180. ← worker, metric
On each Registration, close, poll pick or replay, choose one option and say why. ← triggers, chooses
Enroll every registrant within 24 hours of the close; confirmations carry no Offer. ← copyRules 9
Talk-to-the-team picks go to Priya within 60 minutes. ← your file, line 4
Never call a recorded session live, or show a cap that isn’t real. ← copyRules 3, 4
Invite no Organization in the held-back fifth. ← your file, line 2 The slow loop. The leaf first reads on Dec 7, so the weekly Decisions kept the follow-up rule as written and no Change was merged; there is no replay or read-back to print.
Bring your own agent (folded) starts at It does it, you can stop it on invitations and replays when it matches or beats the seated agent on the eval suite; attendee notes stay with you; POST /{namespace}/roles/{role}/staff seats it.
npx startup-builder eval --scenario events-and-webinars-140 --agent "claude -p" --seat marketing-lead # seated: 6.4 Meetings per 100, 0 Checks failed sent, follow-up in 19 h · yours: 5.7, 1 failed `consent-stop` What it can do next
| Option | Picked when | Decided by | Runs | Hands to | If it’s just you |
|---|---|---|---|---|---|
Plan a series plan-a-series | 10+ questions on one problem in 30 days | Agent’s call, with its reason | POST /{namespace}/gatherings × 3 → publish-content the Pages → POST /{namespace}/approvals | you approve the series, due 1 business day · Take this one | you |
Invite your List invite-your-list | a session is 21 days out, and each yes is recorded | Your rule (line 2) | POST /{namespace}/messages/{message}/broadcast → webinar-registration | nobody | the same |
Follow up an attendee follow-up-an-attendee | attended live | Agent’s call, with its reason | webinar-attendee-follow-up, drafted for your Mailbox | POST /{namespace}/tasks/{task}/assign → you, due 1 business day · Take this one | you |
Send the replay send-the-replay | registered and missed it | Your rule (line 4) | webinar-no-show-follow-up | nobody | the same |
To the AE to-the-ae | picked talk to the team, or asked for a demo, a trial or a Price | Agent’s call, with its reason | POST /{namespace}/tasks/{task}/assign → POST /{namespace}/meetings/book on Priya’s calendar | AE · Priya Shah, due 60 min · Take this one | you, within 60 min |
Cut the replay cut-the-replay | a session closed with the recording notice shown | Your rule (the notice) | POST /{namespace}/videos/draft 3 cuts → POST /{namespace}/posts/{post}/schedule | you approve the cuts | you |
| When they write back | Fixture reply | What happens | Who answers | By when | Call |
|---|---|---|---|---|---|
| Interested | “Yes, let’s talk. Thursday?” | Priya books it; the Brief goes with it (When it hands to you) | AE · Priya Shah (person) | 60 min | POST /{namespace}/meetings/book |
| Send me pricing | “What would 180 units cost?” | over 150 units: Priya quotes the $2,400-a-year plan | AE · Priya Shah (person) | 60 min | POST /{namespace}/quotes/{quote}/send |
| Not now | “After renewal season, please.” | the follow-up stops; the next session’s invite still comes | nobody | at once | POST /{namespace}/enrollments/{enrollment}/cancel |
| Wrong person | “Send this to our leasing manager.” | asks them to forward it; it never writes to an address from their text | Marketing Lead · your agent | 1 business day | POST /{namespace}/conversations/{conversation}/answer |
| Out of office | an auto-reply until Oct 28 | the follow-up waits for the return date | nobody | the return date | POST /{namespace}/messages/{message}/schedule |
| Question it can’t answer | “Can you run this for our owners’ association?” | To a person: a private session is your call | you | 1 business day | POST /{namespace}/conversations/{conversation}/escalate |
| Stop | “Unsubscribe me from these.” | nothing else sends, on any lane, for all your Startups | nobody | at once | POST /{namespace}/contacts/{contact}/suppress |
When it hands to you
Talk-to-the-team picks go to AE · Priya Shah (person); attendee notes and new series come to you. One Brief per Role, as captured (brief is Not live yet, gaps #7).
[
{
"$id": "https://api.sb/leaseline.app/tasks/task_615" ,
"$type": "Task",
"assignee": "worker_3",
"due": "2026-10-13T18:52:00Z" ,
"on": "contact_52",
"brief": {
"who": "Tom Becker, Hearthstone Rentals, 180 units" ,
"said": "picked talk to the team; asked in chat “Does it handle owner approvals?”" ,
"chose": "to-the-ae",
"why": "asked for the team; over 150 units" ,
"attended": "sessions 2 and 3, live" ,
"never": [
"a discount",
"terms",
"his watch minutes"
]
}
},
{
"$id": "https://api.sb/leaseline.app/tasks/task_611" ,
"$type": "Task",
"assignee": "worker_1",
"due": "2026-10-14T18:00:00Z" ,
"on": "contact_61",
"brief": {
"who": "Ana Ruiz, 40 units" ,
"said": "How do owner reports show renewals?" ,
"chose": "follow-up-an-attendee",
"draft": "Thanks for coming, Ana. Your question is answered at 31:40 in the replay; owner reports list each renewal by owner." ,
"never": [
"an Offer in the replay note"
]
}
}
]Priya and you answer with POST /{namespace}/tasks/{task}/claim (Take this one), POST /{namespace}/tasks/{task}/return with a reason, or POST /{namespace}/actions/{action}/redirect, each a one-call window. Once a person claims, the agent’s pending steps to that registrant cancel with claimedByPerson (Not live yet, gaps #7), and every reply goes to the claimer. A Task nobody claims by its due time goes up through POST /{namespace}/tasks/{task}/escalate, and person-promise fires.
On time: AE · Priya Shah, 7 of 7 claimed within 60 min, median 14 min, n 7, ■□□□ Too early to tell; you, 48 of 48 attendee notes within 24 h, median 9 h. Your queue: counted by kind: about 16 attendee notes per session, 2 or 3 hand-offs to Priya, and 1 series approval each quarter.
The fixed line: POST /{namespace}/deals/{deal}/assign sets owner to the receiving person, the agent is never a Deal’s owner, and Meetings land on the owner’s calendar under the owner’s name.
When it won’t send
| Check (refuses one send) | Refuses | Fix | Then |
|---|---|---|---|
owned-by-a-person (rule j; Not live yet, gaps #8) | a follow-up to a registrant whose Lead or open Deal a person owns | Leave it to the person who owns it: the draft waits in their queue. | POST /{namespace}/tasks/{task}/assign |
consent-stop (gaps #3; the record’s Consent stop) | a follow-up to a registrant whose Market needs a recorded yes the Form lacks | Ask once for a yes on the next Form. | POST /{namespace}/messages/{message}/schedule |
claims-resolve (shared) | a sentence in an invite, Page or note that resolves to no record | Cut the claim, or name the record that backs it. | POST /{namespace}/content/draft |
import-refusal (the record’s Import refusal) | a Contact list loaded into the room; everyone registers through the Form | Invite the list; they register themselves. | POST /{namespace}/messages/{message}/broadcast |
partner-box | a Registration shared with a co-host whose box was left unticked | It stays yours; the co-host gets only ticked ones. | PATCH /{namespace}/registrations/{id} |
notice-at-join | a recording with no notice shown at every join | Turn the notice on; that session does not record. | PATCH /{namespace}/gatherings/{id} |
face-voice-consent | a cut with an attendee’s face, voice or full name and no recorded yes | Cut them out, or ask for their yes. | POST /{namespace}/consents |
The captured refusal, then the Stop that fired as a Campaign.paused reason (Not live yet, gaps #2); the rewrite that sent is the second thread in Example.
| Check | Fix | Then |
|---|---|---|
claims-resolve fail | Cut the claim, or name the record that backs it. | POST /{namespace}/content/draft |
consent-stop pass · Not live yet, gaps #3 | — | POST /{namespace}/messages/{message}/schedule |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "The session 2 invitation did not send: “attendees cut vacancy days in half” resolves to no record.",
"checks": [
{
"check": "claims-resolve",
"status": "fail",
"doc": "/plays/events-and-webinars#check-claims-resolve",
"fix": "Cut the claim, or name the record that backs it.",
"then": "Content.draft"
},
{
"check": "consent-stop",
"status": "pass"
}
]
}It says no, says why, and names the fix.
[
{
"reason": {
"limit": "bounce",
"observed": "2.6 % of a day’s invitations",
"bound": "2 %",
"window": "1 day"
},
"doc": "/plays/events-and-webinars#stop-bounce" ,
"task": "task_604"
}
]Did it work
A hashed 20 % of the 820 reachable Organizations was never invited, so both halves read the same random assignment (rules m–o). The leaf matures at day 90 after the first session, Dec 7, so no unit has matured: the counts print with Other Startups’ results, and Added waits. Every node above the leaf is Not live yet (gaps #4).
1.7 against 1.2 Deals per 100 Organizations · ■□□□ Too early to tell · held back at random · n 820 · path → arr
- Chose
- to-the-ae
- Why
- they picked talk to the team in session 3’s closing poll and manage 180 units, over the 150 your Team plan covers
- From
- plan-a-series · invite-your-list · follow-up-an-attendee · send-the-replay · to-the-ae · cut-the-replay
- Expects
- a Meeting held by day 14
- Reopens when
- no Meeting.booked for contact_52 within 14d
- By
- worker_6
JSON
{
"$id": "decisions/decision_486",
"$type": "Decision",
"choice": "to-the-ae",
"reason": "they picked talk to the team in session 3’s closing poll and manage 180 units, over the 150 your Team plan covers",
"stakes": "low",
"options": [
"plan-a-series",
"invite-your-list",
"follow-up-an-attendee",
"send-the-replay",
"to-the-ae",
"cut-the-replay"
],
"by": "worker_6",
"on": "contact_52",
"expected": "a Meeting held by day 14",
"reopensWhen": "no Meeting.booked for contact_52 within 14d"
}| Node | Invited (656 Organizations) | Held back (164) | Added | Confidence | Basis |
|---|---|---|---|---|---|
registrant-deals | 1.7 Deals per 100 Organizations (11 of 656) | 1.2 (2 of 164) | — · reads Dec 7 | ■□□□ Too early to tell | held back at random · n 820 · all still maturing · Other Startups’ results +2.1 per 100, ■■□□ Early sign, n 9,400 Organizations |
opened-deals-and-trials | 2.1 per 100 (14 of 656) | 1.8 (3 of 164) | — | ■□□□ Too early to tell | the same assignment |
new-arr ↑ | $1,735, 5 Customers · Booked: credited, not all caused by this Play | $347, 1 Customer ($1,388 at the invited half’s size) | — · Worth about +$260 a month | ■□□□ Too early to tell (5 vs 1 Customers) | the same · 4 Deals still deciding |
net-new-arr · arr | +$1,735 | +$1,388 scaled | — | ■□□□ Too early to tell | carried from new-arr |
The leaf counts Deals opened per 100 Organizations, invited against held back, read at day 90 and day 180 after the first session; only matured Organizations count (rule n), so nothing prints as Added until Dec 7.
How it moves it: all 140 registrants got the replay and their own answer within a median 9 hours, and the 7 who asked for the team reached Priya in a median 14 minutes.
Guardrails: invited against held back: Deals per Meeting, 1.0 against Other Startups’ 0.9, and unsubscribes, 0.4 % of invitations; 4 Deals are still deciding.
{
"$id": "https://api.sb/leaseline.app/campaigns/events-and-webinars" ,
"$type": "Campaign",
"play": "play:events-and-webinars@1" ,
"path": [
"registrant-deals",
"opened-deals-and-trials",
"new-arr",
"net-new-arr",
"arr"
],
"experiment": {
"metric": "registrant-deals",
"unit": "per-100",
"heldBack": 164,
"decision": null
},
"readout": {
"value": null,
"n": 820,
"maturing": 820,
"interval": null,
"readability": "inadmissible",
"basis": "held-back",
"pooled": false
},
"ledger": {
"spend": 0,
"workerCost": 11,
"hours": 11.5,
"openArr": 4800,
"wonArr": 1735,
"projectedArr": 264,
"paybackDays": 3
}
}Outside benchmark: 32 % of registrants attended live (a webinar-platform vendor’s 2026 B2B benchmark, its own customers only); Leaseline’s series ran 34 %.
Before it · After it. Before it: founder-voice and owned-newsletter reach the people who register. After it: archive-repurposing hears each transcript, retargeting hears the no-shows, and instant-response answers registrants who write in.
Example
Leaseline ran it from 2026-08-24 to 2026-10-19 (56 days): one 3-session series, 1,640 Contacts at 820 Organizations, 164 held back; 140 unique registrants, 48 attended live and 61 watched the replay. Read every captured thread at ?threads=; three follow the tables.
| What happened, by option | Decisions | Sent | Meetings by day 14 · Deals so far |
|---|---|---|---|
| Invite your List · Send the replay | 3 sends · 52 | 1,312 invites · 52 replays | — · — |
| Follow up an attendee | 48 | 48, from your Mailbox | 2 · 2 |
| To the AE | 7 | 7 hand-offs | 7 · 6 |
| Plan a series · Cut the replay | 1 · 3 sessions | 1 series · 7 cuts | — · — |
| All registrants · held-back Organizations | 140 | 9 Meetings (6.4 per 100) | 13 Deals, 5 paid ($1,735) · 2 Deals |
| Day | Event | What happened | Your time |
|---|---|---|---|
| 0 | event_1580 Campaign.created | the three steps; the dry run fails mailbox-warm | 25 min |
| 1 | event_1583 Approval.approved | you approved the series: three sessions on 60-day notices | 15 min |
| 14 | event_1590 POST /{namespace}/messages/{message}/broadcast | session 1 invitations, after events@ finished warming | — |
| 15 | event_1592 Campaign.paused | bounce: 2.6 % of the day’s invitations; one old list source paused | 10 min |
| 15 | event_1594 Gathering.held | session 1: 41 registrants, 15 live; the first Meeting booked that afternoon | 3 h |
| 29 · 50 | event_1604 · event_1633 Gathering.held | sessions 2 and 3: 58 and 64 registrants, 17 and 16 live | 6 h |
| 1–56 | event_1595 Task.assigned, first of 48 | you sent 48 attendee notes, from the POST /{namespace}/tasks/next log | 2 h 15 min · total 11.5 h measured, 10 h asked |
Tom Becker, session 3 chat, Oct 13, 17:41 · “Does it handle owner approvals?” · poll: talk to the team.
Priya, 17:56 · Hi Tom, thanks for staying to the end. Owner approvals are in the replay at 38:10.¹ For 180 units, our account plan fits: would Thu 10:00 or 14:00 Central work?² *Signed with the Role’s disclosure line.*³
Tom, 18:20 · “Thu 14:00.”
POST /{namespace}/meetings/bookput it on Priya’s calendar; a Deal opened on Oct 16.
- Our attendees cut vacancy days in half.
+ Across 3,520 renewals, leases noticed 60+ days out renewed at 71 % (n 1,940). Session 2 shows how. Ana Ruiz, session 3, Oct 13, 17:30 · “How do owner reports show renewals?” · The note went to you (
task_611), due 18:00 on Oct 14; Dana, Oct 14, 09:12 · *sent it from her own Mailbox, with the answer at 31:40 in the replay.*⁴
¹ The answer to their own question, at its minute. ² One next step, with times the calendar shows. ³ The fixed signature line, compiled from the Role’s disclosure Setting. ⁴ The attendee note goes from the host’s own Mailbox.
Your settings
---
holdout: 0.2 # a hashed 1 Organization in 5 is never invited
---
Run three sessions on 60-day notices. Send the replay to every registrant within a day; talk-to-the-team picks go to Priya within 60 minutes. $ npx startup-builder show plays/events-and-webinars
holdout 0.2 · 3 sessions · AE within 60 min your file plays/events-and-webinars.mdx:2,4 (Ask 2026-08-24)
family demand · process content-marketing · worker role:marketing-lead, owns never · chooses 6 (3 rule, 3 read) · sequences webinar-registration, webinar-attendee-follow-up, webinar-no-show-follow-up, webinar-on-demand-follow-up · checks owned-by-a-person, consent-stop, claims-resolve + 4 · stops 8 · placements gmail, outlook, yahoo-mail, linkedin, x, youtube catalog play:events-and-webinars@1 (Not live yet, gaps #5) Every key from the catalog
Compiled, not written: edit the Play record events-and-webinars and its Leaseline run, 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.