Sequences: follow-ups that stop on reply
Timed follow-ups that stop the moment someone replies, books or buys, with conversion by step.
A Sequence is timed follow-ups that stop the moment someone replies, books or buys. Each step costs $0.04 drafted and sent (sample).
Enroll Kestrel Rentals in our nurture follow-ups, then pause them while I talk to them.
curl -X POST "https://api.sb/leaseline.app/contacts/contact_52/enroll?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"sequence":"sequence_3"}'
curl -X POST "https://api.sb/leaseline.app/enrollments/enrollment_17/pause?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"import { $ } from 'startup-builder'
const { enrollment } = await $.Contact.enroll({ contact: 'contact_52', sequence: 'sequence_3' }, { mode: 'try' }) // Assisted nurture: 9 steps, front-loaded into month one
return await $.Enrollment.pause({ enrollment: 'enrollment_17' }, { mode: 'try' }) // “Maybe next quarter.”: the next step waits
npx startup-builder do Contact.enroll --json '{"contact":"contact_52","sequence":"sequence_3"}' --try
npx startup-builder do Enrollment.pause --json '{"enrollment":"enrollment_17"}' --try{
"name": "do",
"arguments": {
"code": "const { enrollment } = await $.Contact.enroll({ contact: 'contact_52', sequence: 'sequence_3' }, { mode: 'try' }) // Assisted nurture: 9 steps, front-loaded into month one\nreturn await $.Enrollment.pause({ enrollment: 'enrollment_17' }, { mode: 'try' }) // “Maybe next quarter.”: the next step waits",
"mode": "try"
}
}application/json{
"enrollment": {
"$id": "https: //api.sb/ leaseline.app/ enrollments/ enrollment_17",
"$type": "Enrollment",
"status": "paused",
"step": "outcome",
"nextAt": null,
"contact": {
"$id": "https: //api.sb/ leaseline.app/ contacts/ contact_52",
"$type": "Contact",
"name": "Sam Ortiz"
},
"sequence": {
"$id": "https: //api.sb/ leaseline.app/ sequences/ sequence_3",
"$type": "Sequence"
},
"mode": "try"
}
}
sampleWhat it does
| What you pay for | Price per unit (sample) | The call |
|---|---|---|
| A step drafted and sent | $0.04 | POST /{namespace}/contacts/{contact}/enroll |
| A pause or a resume | $0 | POST /{namespace}/enrollments/{enrollment}/pause |
Run it
| Step | Call | What it does here |
|---|---|---|
| 1 | POST /{namespace}/contacts/{contact}/enroll | Assisted nurture: 9 steps, front-loaded into month one |
| 2 | POST /{namespace}/enrollments/{enrollment}/pause | “Maybe next quarter.”: the next step waits |
Set it up
| Check | On the day-0 Startup | Fix | Your time | Wait | Then |
|---|---|---|---|---|---|
suppressed-contact | pass | enrolling a suppressed Contact refuses | 0 min | none | POST /{namespace}/collections/query |
no-consent | pass | each step reads Consent for its purpose before it sends | 0 min | none | POST /{namespace}/consents |
mailbox-warm | pass | steps send only from a warmed Mailbox | 0 min | 14 days from day 0 | POST /{namespace}/mailboxes/{mailbox}/warm |
---
sequence: nurture-assisted
play: lead-nurture
sending: as-itself
steps:
- { id: proof, wait: 1d, medium: email }
- { id: outcome, wait: 4d, medium: email }
- { id: question, wait: 2d, medium: email }
- { id: offer, wait: 7d, medium: email }
- { id: use-case, wait: 7d, medium: email }
- { id: month-one-close, wait: 7d, medium: email }
- { id: value-42, wait: 14d, medium: email }
- { id: value-63, wait: 21d, medium: email }
- { id: pausing, wait: 21d, medium: email }
exitOn:
- A reply
- A paid Order or Subscription
- A stop at any scope
- A hard bounce
- A Deal opened after a held Meeting
- 90 days with no Lead Event
- Day 180
---The records
{
"enrollment": {
"$id": "https://api.sb/leaseline.app/enrollments/enrollment_17" ,
"$type": "Enrollment",
"status": "paused",
"step": "outcome",
"nextAt": null,
"exitReason": null
}
}| Step | Wait | Message | Exits on |
|---|---|---|---|
proof | 1d | One proof fact matched to the Lead’s interest. | A reply · A paid Order or Subscription · A stop at any scope · A hard bounce · A Deal opened after a held Meeting · 90 days with no Lead Event · Day 180 |
outcome | 4d | A verified Customer outcome like theirs, or a Sample. | the same |
question | 2d | One plain-text question. | the same |
offer | 7d | The entry Offer as the Pricing Page states it, with a booking link. | the same |
use-case | 7d | The use case for the Lead’s role, from the claims source. | the same |
month-one-close | 7d | The month-one close: the Offer, two times, and a monthly-only choice. | the same |
value-42 | 14d | A new fact matching the interest; skipped when none exists. | the same |
value-63 | 21d | A new fact matching the interest; skipped when none exists. | the same |
pausing | 21d | A new fact if one exists, the note that the Play is pausing, and how to reach a person. | the same |
+4.1 per 100 · ■■□□ Early sign · n 412 · path → arr
Conversion by step, sample until captured: replies or bookings per 100 who reached the step, read with POST /{namespace}/metrics/query on nurture-conversion by step.
| Step | Reached (n) | Replied or booked, per 100 | Confidence |
|---|---|---|---|
proof | 412 | 3.4 | ■■□□ Early sign |
outcome | 398 | 2.8 | ■■□□ Early sign |
question | 371 | 4.6 | ■■□□ Early sign |
offer | 340 | 5.9 | ■■□□ Early sign |
use-case | 301 | 1.7 | ■■□□ Early sign |
month-one-close | 277 | 4.3 | ■■□□ Early sign |
value-42 | 231 | 0.9 | ■■□□ Early sign |
value-63 | 204 | 0.5 | ■■□□ Early sign |
pausing | 188 | 1.1 | ■■□□ Early sign |
Calls
| Call | What it does | What else happens | Event |
|---|---|---|---|
POST /{namespace}/contacts/{contact}/enroll | Enroll adds a Contact to a Sequence, which sends its steps until the Contact replies or exits. | Refuses a suppressed Contact or one with no consent for the Sequence’s purpose. | Contact.enrolled |
POST /{namespace}/enrollments/{enrollment}/pause | Pause stops one Contact’s run through a Sequence at its current step, without ending it. | — | Enrollment.paused |
POST /{namespace}/enrollments/{enrollment}/resume | Resume restarts a paused run at the step it stopped on and sets when that step fires. | Sets nextAt from the step’s wait, counted from now. | Enrollment.resumed |
POST /{namespace}/enrollments/{enrollment}/cancel | Cancel ends one Contact’s run through a Sequence for good, with the reason it records as exitReason. | — | Enrollment.canceled |
POST /{namespace}/sequences | Not in the hub registry snapshot. | Today: — | — |
Events
{
"$id": "https://api.sb/leaseline.app/events/event_1" ,
"$type": "Event",
"name": "Contact.enrolled",
"at": "2026-10-22T12:00:00Z" ,
"seq": 1,
"data": {
"contact": {
"$id": "https://api.sb/leaseline.app/contacts/contact_1" ,
"$type": "Contact",
"email": "dana@leaseline.app",
"phone": "Example phone"
},
"enrollment": {
"$id": "https://api.sb/leaseline.app/enrollments/enrollment_1" ,
"$type": "Enrollment",
"status": "active",
"step": "Example step"
}
}
}{
"$id": "https://api.sb/leaseline.app/events/event_1" ,
"$type": "Event",
"name": "Enrollment.paused",
"at": "2026-10-22T12:00:00Z" ,
"seq": 1,
"data": {
"enrollment": {
"$id": "https://api.sb/leaseline.app/enrollments/enrollment_1" ,
"$type": "Enrollment",
"status": "active",
"step": "Example step"
}
}
}{
"$id": "https://api.sb/leaseline.app/events/event_1" ,
"$type": "Event",
"name": "Enrollment.resumed",
"at": "2026-10-22T12:00:00Z" ,
"seq": 1,
"data": {
"enrollment": {
"$id": "https://api.sb/leaseline.app/enrollments/enrollment_1" ,
"$type": "Enrollment",
"status": "active",
"step": "Example step"
}
}
}{
"$id": "https://api.sb/leaseline.app/events/event_1" ,
"$type": "Event",
"name": "Enrollment.canceled",
"at": "2026-10-22T12:00:00Z" ,
"seq": 1,
"data": {
"enrollment": {
"$id": "https://api.sb/leaseline.app/enrollments/enrollment_1" ,
"$type": "Enrollment",
"status": "active",
"step": "Example step"
}
}
}{
"$id": "https://api.sb/leaseline.app/events/event_1" ,
"$type": "Event",
"name": "Sequence.created",
"at": "2026-10-22T12:00:00Z" ,
"seq": 1,
"data": {
"sequence": {
"$id": "https://api.sb/leaseline.app/sequences/sequence_1" ,
"$type": "Sequence",
"steps": {}
}
}
}Refuses when
| Check | Refuses | Fix | Then |
|---|---|---|---|
suppressed-contact | a send or Sequence step to a Contact on a Suppression, from any Play | Leave them out: run the List again, which drops every suppressed Contact. | POST /{namespace}/collections/query |
no-consent | a send or Sequence step whose purpose the Contact has given no Consent for | Record the Contact’s yes, with where they gave it, before the first send. | POST /{namespace}/consents |
mailbox-warm Not live yet · gaps #1 · today: The 422 renders from the sample; POST /{namespace}/mailboxes/{mailbox}/warm, POST /{namespace}/approvals/{approval}/approve and POST /{namespace}/leads/{lead}/assign clear it. | a first cold email from a Mailbox that has not finished warming | Wait for the warm-up to finish, 14 days from day 0; warm intros keep running. | POST /{namespace}/mailboxes/{mailbox}/warm |
| Check | Fix | Then |
|---|---|---|
suppressed-contact fail | Leave them out: run the List again, which drops every suppressed Contact. | POST /{namespace}/collections/query |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "Step two to Lakeside Rentals’ owner did not send: they asked us to stop on Oct 12.",
"checks": [
{
"check": "suppressed-contact",
"status": "fail",
"observed": "Suppression suppression_6, unsubscribed 2026-10-12",
"doc": "/code/refusals#check-suppressed-contact",
"fix": "Leave them out: run the List again, which drops every suppressed Contact.",
"then": "Collection.query"
}
]
}It says no, says why, and names the fix.
| Check | Fix | Then |
|---|---|---|
suppressed-contact pass | — | POST /{namespace}/collections/query |
no-consent fail | Record the Contact’s yes, with where they gave it, before the first send. | POST /{namespace}/consents |
JSON
{
"type": "https://startupbuilder.dev/errors/refused",
"title": "Refused",
"status": 422,
"detail": "Pinecrest Homes’ second visitor was not enrolled: no Consent on record for sales email.",
"checks": [
{
"check": "suppressed-contact",
"status": "pass"
},
{
"check": "no-consent",
"status": "fail",
"observed": "no Consent for purpose sales-email",
"doc": "/code/refusals#check-no-consent",
"fix": "Record the Contact’s yes, with where they gave it, before the first send.",
"then": "Consent.create"
}
]
}It says no, says why, and names the fix.
Pauses when
| Stop | Pauses when | Fix | Then |
|---|---|---|---|
unanswered-positive | a reply asking to meet that waits 60 minutes for a person | Answer the reply, then approve the resume. | POST /{namespace}/approvals/{approval}/approve |
kill-switch | you press it, or the injection Stop fires | Review what fired, then turn the Process back on. | POST /{namespace}/processes/{process}/enable |
{
"$id": "https://api.sb/leaseline.app/events/event_951" ,
"$type": "Event",
"name": "Campaign.paused",
"at": "2026-10-19T16:45:00Z" ,
"data": {
"campaign": {
"$id": "https://api.sb/leaseline.app/campaigns/cold-email" ,
"$type": "Campaign"
},
"reason": {
"limit": "unanswered-positive",
"observed": "64m",
"bound": "60m",
"window": "60m"
},
"task": {
"$id": "https://api.sb/leaseline.app/tasks/task_88" ,
"$type": "Task"
}
}
}Plays that use it
| Play | What it does | Its Metric |
|---|---|---|
| Lead nurture | Follows up each unbought Lead with notes keyed to what they did, most in month one, until they buy, reply or go quiet 90 days. | nurture-conversion |
Metric it reaches: Nurture conversion (nurture-conversion).
Hub guides it deepens
| On startupbuilder.dev | Id | What it holds |
|---|---|---|
| Sequence | noun: | the record, its fields and every call on it |
| Enrollment | noun: | the record, its fields and every call on it |
Example
| Leaseline, when | What happened | Cost (sample) |
|---|---|---|
| 2026-10-14 | Kestrel Rentals enters Assisted nurture | $0 |
| 2026-10-19 | after step two, Sam replies “Maybe next quarter”; Dana pauses it while she calls | $0.08 for 2 steps |
Compiled, not written: edit its page, 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.