The sequences/ folder: one file and what it compiles to
What one sequences/ file holds, what each key compiles to, and the checks that read it.
One sequences/ file is one Sequence: its steps, waits and the replies that end it. SalesBuilder compiles it, and show traces every key.
---
sending: for-human
steps:
- { id: first, send: email }
- { id: second, wait: 3d, send: email }
- { id: third, wait: 7d, send: email }
- { id: park, wait: 30d, branch: first }
exitOn: ["Message.created where direction = 'inbound'", Contact.suppressed, Meeting.booked, Deal.created]
---
Three emails from Dana’s own Mailbox, then a 30-day park. $ npx startup-builder show sequences/cold-email-thread-founder.mdx
sending for-human sequences/cold-email-thread-founder.mdx:2
steps sequences/cold-email-thread-founder.mdx:3
exitOn ["Message.created where direction = 'inbound'", Contact.suppressed, Mee… sequences/cold-email-thread-founder.mdx:8
owner SalesBuilderleaseline.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/ ← this folder
│ └── 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/
│ ├── pro.mdx
│ └── team.mdx
├── content/
│ └── webinars/60-day-notices.mdx
├── metrics/
│ ├── q4.mdx
│ └── positive-reply-rate.mdx
└── startups.lockThe file
| Key | On the page | Compiles to | Checked by |
|---|---|---|---|
sending | Sends as | who the send is from: itself, or a person under their Mandate | — |
steps | Steps | one send or wait per step; each send passes a code-tier Check | S2 |
exitOn | Stops on | Event selectors that end the Enrollment (POST /{namespace}/enrollments/{enrollment}/pause) | S5 |
Checks
| Check | It holds | What dev prints |
|---|---|---|
| S2 | Every send passes a code-tier Check before it goes. | sequences/ |
| S5 | Every on: names a registered Event. | plays/ |
Refusals
| Code | Fix, then the call that clears it |
|---|---|
address-cap | Bundle the extra Tenants into the next message; the cap resets after 24 hours. Then POST /{namespace}/messages/{message}/schedule. |
claim | Cut the line, or cite the Offer term that grants it. Then POST /{namespace}/conversations/{conversation}/answer. |
consent-stop | Ask once for a yes to the other Startup. Then POST /{namespace}/messages/{message}/schedule. |
correction-cap | Hold the correction for next week, or 30 days for the same Contact. Then POST /{namespace}/messages/{message}/schedule. |
count-floor | Say “2 people on your team”, never a name. Then POST /{namespace}/messages/{message}/schedule. |
customer-collision | Send it to their CSM instead: the Contact leaves the List. Then POST /{namespace}/leads/{lead}/assign. |
display-consent | Ask the reviewer once; the Review shows when they agree. Then POST /{namespace}/messages/{message}/schedule. |
domain-authenticated | Add the 3 DNS records shown; it passes once they resolve, often within an hour. Then POST /{namespace}/domains/{domain}/authenticate. |
double-opt-in | Wait for their yes on the introducer’s thread. Then GET /{namespace}/decisions. |
evidence | Ask the publisher for subscriber and open numbers first. Then POST /{namespace}/messages/{message}/schedule. |
gift-cap | Pick a gift under the class cap, or send none to that Organization. Then POST /{namespace}/messages/{message}/schedule. |
invite-bounce | Ask the referrer to share the link instead of typing addresses. Then POST /{namespace}/messages/{message}/schedule. |
mailbox-warm | Wait for the warm-up to finish, 14 days from day 0; warm intros keep running. Then POST /{namespace}/mailboxes/{mailbox}/warm. |
movement-limit | Wait 30 days, or 180 days after 3 unanswered notes; send upward moves only. Then POST /{namespace}/messages/{message}/schedule. |
named-score | Get recorded Consent and the founder's approval, or leave the name out. Then POST /{namespace}/messages/{message}/schedule. |
no-consent | Record the Contact’s yes, with where they gave it, before the first send. Then POST /{namespace}/consents. |
obligation-void | Send the help Messages; the guarantee stands until then. Then POST /{namespace}/messages/{message}/schedule. |
opt-in | Send the introducer their opt-in page first. Then POST /{namespace}/messages/{message}/schedule. |
owned-by-a-person | Leave it to the person who owns it: the draft waits in their queue. Then POST /{namespace}/tasks/{task}/assign. |
paying-user | Wait for the first paying connection; send the private link to one. Then POST /{namespace}/messages/{message}/schedule. |
price | Get the discount approved, or quote at the floor. Then POST /{namespace}/approvals/{approval}/approve. |
quiet-hours | Wait for their window; the narrower of two time zones wins. Then POST /{namespace}/messages/{message}/schedule. |
renewal-notice | Send the renewal notice with its amount; the renewal waits 30 days after it. Then POST /{namespace}/messages/{message}/schedule. |
rights-hold | Ask the host for the grant; the Page waits for it. Then POST /{namespace}/messages/{message}/schedule. |
spam-brake | Send to a smaller List, or wait an hour for the rate to fall. Then POST /{namespace}/messages/{message}/broadcast. |
supplied-address | Ask where to send it in the thread; ship only to their answer. Then POST /{namespace}/messages/{message}/schedule. |
suppressed-contact | Leave them out: run the List again, which drops every suppressed Contact. Then POST /{namespace}/collections/query. |
visit-in-copy | Open on a public fact about the company instead. Then POST /{namespace}/messages/{message}/schedule. |
Calls
You, to your agent
Create the founder thread, enroll one Contact, then pause them, as a dry run.
curl -X POST "https://api.sb/leaseline.app/sequences?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"steps":{}}'
curl -X POST "https://api.sb/leaseline.app/contacts/contact_1/enroll?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"sequence":"sequence_1"}'
curl -X POST "https://api.sb/leaseline.app/enrollments/enrollment_1/pause?mode=try" \
-H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"import { $ } from 'startup-builder'
await $.Sequence.create({ steps: {} }, { mode: 'try' }) // sequences/ cold-email-thread-founder.mdx
await $.Contact.enroll({ contact: 'contact_1', sequence: 'sequence_1' }, { mode: 'try' })
return await $.Enrollment.pause({ enrollment: 'enrollment_1' }, { mode: 'try' }) // a reply pauses it the same way
npx startup-builder do Sequence.create --json '{"steps":{}}' --try
npx startup-builder do Contact.enroll --json '{"contact":"contact_1","sequence":"sequence_1"}' --try
npx startup-builder do Enrollment.pause --json '{"enrollment":"enrollment_1"}' --try{
"name": "do",
"arguments": {
"code": "await $.Sequence.create({ steps: {} }, { mode: 'try' }) // sequences/cold-email-thread-founder.mdx\nawait $.Contact.enroll({ contact: 'contact_1', sequence: 'sequence_1' }, { mode: 'try' })\nreturn await $.Enrollment.pause({ enrollment: 'enrollment_1' }, { mode: 'try' }) // a reply pauses it the same way",
"mode": "try"
}
}Response200
application/json{
"enrollment": {
"$id": "https: //api.sb/ leaseline.app/ enrollments/ enrollment_1",
"$type": "Enrollment",
"status": "active",
"step": "Example step"
},
"action": {
"$id": "https: //api.sb/ leaseline.app/ actions/ action_1",
"operation": "Enrollment.pause",
"status": "done"
}
}
sample| Call | What it does |
|---|---|
POST /{namespace}/contacts/{contact}/enroll | Enroll adds a Contact to a Sequence, which sends its steps until the Contact replies or exits. Emits Contact.enrolled. |
POST /{namespace}/enrollments/{enrollment}/pause | Pause stops one Contact’s run through a Sequence at its current step, without ending it. Emits Enrollment.paused. |
POST /{namespace}/leads/{lead}/nurture | Nurture takes a Lead that is not ready to buy off its owner’s queue and onto a Sequence, until it raises a hand again. Emits Lead.nurtured. |
POST /{namespace}/messages/{message}/schedule | Schedule holds a Message until a set time and sends it then, unless it is canceled first. Emits Message.scheduled. |
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.