Headless SaaS: every write is one record and one Event
Your CRM, sequences, inboxes, social, ads and analytics, as calls your agents make on one record, with a screen only where you want one.
- Deepens
- Software, Headless SaaS, Integrations
- Systems
- 12
- Integrations
- 25
- Action Verbs
- 16
- Workflows
- 21
- First call
Contact.enroll
Enroll the 50 verified heads of operations in my three-email sequence from my two warmed inboxes, and show me the first send.
curl -X POST "https: //api.sb/ leaseline.app/ contacts/ enroll? mode= try" \
-H "Authorization: Bearer $SB_TOKEN" \
-H "Content-Type: application/ json" \
-d '{"audience": "audiences/ heads-of-operations", "sequence": "sequences/ first-touch", "from": ["dana@tryleaseline.app", "sales@tryleaseline.app"]}'
npx startup-builder do Contact.enroll --try --data '{"audience": "audiences/ heads-of-operations", "sequence": "sequences/ first-touch", "from": ["dana@tryleaseline.app", "sales@tryleaseline.app"]}'
{
"name": "do",
"arguments": {
"mode": "try",
"code": "return await $.Contact.enroll({ audience: 'audiences/ heads-of-operations', sequence: 'sequences/ first-touch', from: ['dana@tryleaseline.app', 'sales@tryleaseline.app'] })"
}
}
import { $ } from 'startup-builder'
const result = await $.try.Contact.enroll({ audience: 'audiences/ heads-of-operations', sequence: 'sequences/ first-touch', from: ['dana@tryleaseline.app', 'sales@tryleaseline.app'] })
{
"mode": "try",
"stored": false,
"enrolled": 50,
"sequence": "sequences/ first-touch",
"from": [
"dana@tryleaseline.app",
"sales@tryleaseline.app"
],
"pace": {
"perInboxPerDay": 25,
"under": "mandates/ sdr-outbound"
},
"firstSend": {
"to": "dana@harborview-pm.com",
"step": 1,
"at": "2026-10-28T15: 00: 00Z",
"subject": "Rent ledgers at Harborview"
},
"skipped": []
}
The reference for every call on this page is the App API.
Your sales apps run without a dashboard
Each app is a hub System run headless: its Nouns, the Verbs that change them, and the Events each change emits. Your agents call them, and you open a screen only when you want one.
The set covers the whole funnel. Prospecting, Sequences and Mailboxes carry outreach. Scheduling turns a reply into a booked call, and the CRM holds every lead and deal.
Social posts from your own accounts on LinkedIn, X, Reddit, YouTube, TikTok and Instagram. Ads runs Campaigns on your own Meta, Google, LinkedIn, Reddit, X and TikTok ad accounts. SEO and sites and content hold the pages, the terms they target, and whether each one is indexed.
Quotes, Success and the ARR bridge are Systems too, and they live under Revenue.
| System | Nouns | Five main Verbs | Integrations it reaches | Reference |
|---|---|---|---|---|
| CRM | Contact, Organization, Lead, Deal | Lead.qualify, Lead.assign, Deal.advance, Deal.win, Deal.lose | The CRM you already use | App API |
| Prospecting | Prospect, ICP, Audience | Prospect.engage, Prospect.create, Prospect.update, ICP.create | App API | |
| Sequences | Sequence, Enrollment, Funnel | Contact.enroll, Enrollment.pause, Enrollment.resume, Enrollment.cancel, Lead.nurture | Gmail, Outlook, LinkedIn | App API |
| Mailboxes | Mailbox, Message, Suppression, Consent | Message.schedule, Message.broadcast, Mailbox.warm, Mailbox.rest, Domain.authenticate | Gmail, Outlook | App API |
| Scheduling | Meeting | Meeting.book, Meeting.create, Meeting.update, Meeting.list | Google Calendar, Gmail, Outlook | App API |
| Social | Handle, Post | Post.publish, Post.schedule, Post.withdraw, Handle.connect, Post.create | LinkedIn, X account, Reddit, Hacker News, Product Hunt, YouTube, TikTok, Instagram, Facebook | App API |
| Ads | Campaign, Ad, Audience, Demand Budget | Campaign.create, Campaign.update, Ad.create, Audience.create, Mandate.spend | Meta Ads, Google Ads, Microsoft Ads, LinkedIn Ads, Reddit Ads, X Ads, TikTok Ads | App API |
| SEO | Keyword, Page, Monitor, Domain | Keyword.track, Keyword.create, Keyword.update, Monitor.update | Google Search Console, Bing Webmaster, Google Analytics | App API |
| Sites and content | Site, Page, Content, Domain | Content.draft, Content.publish, Site.publish, Page.create, Page.update | Google Search Console, Bing Webmaster, Google Business Profile | App API |
| Media | Video, File, Voice | Video.draft, Video.finalize, File.generate, File.edit, Voice.clone | YouTube, TikTok, Instagram | App API |
| Forms and waitlists | Form, Waitlist, Visitor | Waitlist.join, Waitlist.admit, Visitor.identify, Visitor.merge, Form.create | Google Analytics | App API |
| Analytics and experiments | Visit, Metric, Experiment, Hypothesis, Dashboard | Metric.query, Metric.watch, Experiment.start, Experiment.conclude, Dashboard.ask | Google Analytics, Google Search Console | App API |
Your sales apps are Software: the tool works
Headless SaaS is the hub's Software kind, delivered through the Headless SaaS template: no App of its own, used through the API, the CLI, the MCP server and the SDK. You never buy these Systems one by one: every startup inherits them, metered by the call.
Its promise is testable: every write is one record, one Event, on every interface. A Workflow (it promises its steps run) is Software too, so the Workflows live here.
One record runs across every app
A contact is the same Thing in the CRM, in Sequences and in Mailboxes. Enrolling it, emailing it and marking it won all write to one record, so no app holds a copy that drifts.
Every Verb is one Tool under one name on every Interface: the SDK, the REST API, the CLI and the MCP do tool. In try mode a call reads and plans, stores nothing and sends nothing.
import { $ } from 'startup-builder'
const plan = await $.try.Contact.enroll({ audience: 'audiences/heads-of-operations' , sequence: 'sequences/first-touch' , from: ['dana@tryleaseline.app', 'sales@tryleaseline.app'] })Every change is an Event agents hear
Each write emits the Event named for its Verb, such as Contact.enrolled or Post.published. A webhook carries it out, and a Watch delivers it to any agent that subscribes.
A Trigger can start a Workflow on it unchanged, and Metric.query reads it back as a trend. Events and webhooks lists every one.
Your accounts plug in three ways
Each call runs on market data, on your connected account, or through a browser agent where a site has no API. Ranked Mappings choose the way, never the caller, and one standing approval bounds all three.
Every send passes one check before it leaves
Before any message, post or enrollment goes out, the platform reads Consent, every Suppression, the Mailbox cap and your standing approval that covers the send.
A failed check refuses that one send with its code and its fix, and the rest of the batch goes on. Checks lists every code, and none of them costs anything.
Keep the CRM you already use
Mirror it or import it, and name the side that leads for each record. A mirror reads and writes through the CRM you already use, and your agents call the same Verbs either way.
The hub's integrations sets the rule: a Source swaps behind a Verb, and the calls stay the same.
Screens appear only where you want them
Each System has an Admin view that lists its records and their history. Anything else is a question: Dashboard.ask turns one sentence into a Dashboard, and Dashboard.schedule sends it every Monday.
Analytics and experiments holds the numbers behind it, so a chart and an agent read the same Metric.