App API
Your sales and marketing Systems as Nouns, Verbs and Events on one key: apps your agents call instead of screens they click.
Enroll the 50 verified heads of operations in my three-email sequence from my warmed second domain, 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"}'
npx startup-builder do Contact.enroll --try --data '{"audience": "audiences/ heads-of-operations", "sequence": "sequences/ first-touch", "from": "dana@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' })"
}
}
import { $ } from 'startup-builder'
const result = await $.try.Contact.enroll({ audience: 'audiences/ heads-of-operations', sequence: 'sequences/ first-touch', from: 'dana@tryleaseline.app' })
{
"mode": "try",
"stored": false,
"enrolled": 50,
"sequence": "sequences/ first-touch",
"from": "dana@tryleaseline.app",
"pace": {
"perDay": 25,
"under": "mandates/ sdr-cold-email"
},
"firstSend": {
"to": "dana@harborview-pm.com",
"step": 1,
"at": "2026-10-28T15: 00: 00Z",
"subject": "Rent ledgers at Harborview"
},
"skipped": []
}
The overview, in a founder's words: Headless SaaS: every write is one record and one Event.
Each System holds your sales records as calls
Each System is a hub System run headless: its Nouns, the Verbs that change them, and the Events each change emits. A System page projects every Noun and Verb definition from the hub, and adds only the integrations it reaches and the seats that work in it. The Revenue Systems (Quotes, Success and the ARR bridge) live under Revenue.
| System | What it holds | Verbs | Events | Its action Verb pages |
|---|---|---|---|---|
| CRM | Your Contacts, Organizations, leads and deals on one record, with qualify, assign, advance and win as calls every agent and app shares. | 13 | 10 | Lead.qualify |
| Prospecting | People who have never engaged, found from a sentence, checked for a working address, and saved with the reason each one fits. | 4 | 4 | None. |
| Sequences | Timed series of emails and tasks for one Contact at a time, enrolled by one call, stopped on any reply, and ended by an unsubscribe. | 8 | 6 | Contact.enroll |
| Mailboxes | The addresses your agents send from, warmed, rested and authenticated, with every Suppression and Consent read before each send. | 9 | 9 | Message.broadcast, Message.schedule |
| Scheduling | A booking link into each seat’s free hours, so an interested reply becomes a booked Meeting with a brief, not a thread of emails. | 4 | 2 | Meeting.book |
| Social | Posts from your own accounts on LinkedIn, X, Reddit, YouTube, TikTok and Instagram, published or scheduled by one call per site. | 6 | 5 | Post.publish, Post.schedule |
| Ads | Audiences, Campaigns and Ads on your own Meta, Google, Bing, LinkedIn, Reddit, X and TikTok ad accounts, spent only under a standing approval. | 6 | 6 | Ad.create, Audience.create, Campaign.create, Campaign.update |
| SEO | The search terms and AI questions your pages target, where each ranks, which answers cite you, and whether every page is indexed. | 4 | 4 | None. |
| Sites and content | Your Site, its pages and the Content on them, drafted from what ranks, published by one call, and submitted to search engines on every publish. | 8 | 6 | None. |
| Media | Videos, images and voice made from your records, cut to each site’s format, and finalized only once every claim reads from a live record. | 6 | 6 | None. |
| Forms and waitlists | Forms and Waitlists turn a visit into a lead, and the Visitor record joins earlier visits to the Contact once they sign up. | 6 | 6 | None. |
| Analytics and experiments | Every visit and Event as Metrics you query, watch and test against, so each Play is read by its number and not by a hunch. | 9 | 8 | Metric.query |
The action Verbs are where your agents act
Each action Verb has its own page: Inputs, Outputs, Effects, what each site honors, what try does, and what refuses it. The four account calls (Integration.connect, Integration.call, Handle.connect and Mandate.authorize) live under Integrations.
| Verb | System | What it changes | Page |
|---|---|---|---|
Post.publish | Social | Puts a Post live from your account on one site, by API or by a browser agent signed in as you | Post.publish |
Post.schedule | Social | Places a drafted Post on its account’s calendar for a set time | Post.schedule |
Message.schedule | Mailboxes | Holds one Message until its send time, then sends it from your Mailbox | Message.schedule |
Message.broadcast | Mailboxes | Sends one Message to an Audience, now or at a set time | Message.broadcast |
Contact.enroll | Sequences | Starts each Contact on a Sequence, which stops on any reply | Contact.enroll |
Meeting.book | Scheduling | Books a Meeting at a time both calendars hold free | Meeting.book |
Audience.create | Ads | Matches a saved list of Prospects or customers to an Audience on your ad account | Audience.create |
Campaign.create | Ads | Creates a Campaign on your ad account, with its stop rule, on spend you authorized | Campaign.create |
Campaign.update | Ads | Changes a live Campaign’s budget, bids or status | Campaign.update |
Ad.create | Ads | Adds an Ad, with its creative in the site’s format, to a Campaign | Ad.create |
Metric.query | Analytics and experiments | Nothing: it reads a Metric as a trend, funnel or retention curve | Metric.query |
Lead.qualify | CRM | Confirms a lead fits an offer and opens a deal for it | Lead.qualify |
Every call takes the same four forms on one key
A System 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 the 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',
})npm i startup-builder@0.3
npx startup-builder do Contact.enroll --data '{"audience":"audiences/heads-of-operations","sequence":"sequences/first-touch"}' Every change emits one Event you can hear
Each write emits the Event named for its Verb, such as Contact.enrolled or Post.published, and a webhook carries it out. A Trigger can start a Workflow on it unchanged, and Metric.query reads it back. Events and webhooks lists every one.
Every send passes one check before it leaves
Before any Message, Post or enrollment goes out, the platform reads Consent and 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, listed at Checks, and the rest of the batch goes on.