URL: /capabilities/apps · Id: `page:/capabilities/apps`

# 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.

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:** [`noun:software`](https://startupbuilder.dev/business/nouns/software), [`product-template:headless-saas`](https://startupbuilder.dev/products/templates/headless-saas), [`capability:integrations`](https://startupbuilder.dev/code/platform/integrations)
- **Systems:** [12](/code/apps)
- **Integrations:** [25](/code/integrations)
- **Action Verbs:** [16](/code/apps#action-verbs)
- **Workflows:** [21](/capabilities/how-calls-compose#catalog)
- **First call:** [`Contact.enroll`](/code/apps/sequences/enroll)

```text title="Run it · Ask"
Enroll the 50 verified heads of operations in my three-email sequence from my two warmed inboxes, and show me the first send.
```

```ts title="Run it · SDK"
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'] })
```

```json title="Run it · Response"
{
  "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](/code/apps).

## Your sales apps run without a dashboard
Each app is a hub [System](https://startupbuilder.dev/business/nouns/system) run headless: its [Nouns](https://startupbuilder.dev/business/nouns/noun), the [Verbs](https://startupbuilder.dev/business/nouns/verb) that change them, and the [Events](/code/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](/code/apps/prospecting), [Sequences](/code/apps/sequences) and [Mailboxes](/code/apps/mailboxes) carry outreach. [Scheduling](/code/apps/scheduling) turns a reply into a booked call, and the [CRM](/code/apps/crm) holds every lead and deal.

[Social](/code/apps/social) posts from your own accounts on LinkedIn, X, Reddit, YouTube, TikTok and Instagram. [Ads](/code/apps/ads) runs Campaigns on your own Meta, Google, LinkedIn, Reddit, X and TikTok ad accounts. [SEO](/code/apps/seo) and [sites and content](/code/apps/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](/revenue).

| System | Nouns | Five main Verbs | Integrations it reaches | Reference |
| --- | --- | --- | --- | --- |
| [CRM](/code/apps/crm) | [`noun:contact`](https://startupbuilder.dev/business/nouns/contact), [`noun:organization`](https://startupbuilder.dev/business/nouns/organization), [`noun:lead`](https://startupbuilder.dev/business/nouns/lead), [`noun:deal`](https://startupbuilder.dev/business/nouns/deal) | [`Lead.qualify`](/code/apps/crm/qualify), `Lead.assign`, `Deal.advance`, `Deal.win`, `Deal.lose` | The CRM you already use | [App API](/code/apps/crm) |
| [Prospecting](/code/apps/prospecting) | [`noun:prospect`](https://startupbuilder.dev/business/nouns/prospect), [`noun:icp`](https://startupbuilder.dev/business/nouns/icp), [`noun:audience`](https://startupbuilder.dev/business/nouns/audience) | `Prospect.engage`, `Prospect.create`, `Prospect.update`, `ICP.create` | LinkedIn | [App API](/code/apps/prospecting) |
| [Sequences](/code/apps/sequences) | [`noun:sequence`](https://startupbuilder.dev/business/nouns/sequence), [`noun:enrollment`](https://startupbuilder.dev/business/nouns/enrollment), [`noun:funnel`](https://startupbuilder.dev/business/nouns/funnel) | [`Contact.enroll`](/code/apps/sequences/enroll), `Enrollment.pause`, `Enrollment.resume`, `Enrollment.cancel`, `Lead.nurture` | Gmail, Outlook, LinkedIn | [App API](/code/apps/sequences) |
| [Mailboxes](/code/apps/mailboxes) | [`noun:mailbox`](https://startupbuilder.dev/business/nouns/mailbox), [`noun:message`](https://startupbuilder.dev/business/nouns/message), [`noun:suppression`](https://startupbuilder.dev/business/nouns/suppression), [`noun:consent`](https://startupbuilder.dev/business/nouns/consent) | [`Message.schedule`](/code/apps/mailboxes/schedule), [`Message.broadcast`](/code/apps/mailboxes/broadcast), `Mailbox.warm`, `Mailbox.rest`, `Domain.authenticate` | Gmail, Outlook | [App API](/code/apps/mailboxes) |
| [Scheduling](/code/apps/scheduling) | [`noun:meeting`](https://startupbuilder.dev/business/nouns/meeting) | [`Meeting.book`](/code/apps/scheduling/book), `Meeting.create`, `Meeting.update`, `Meeting.list` | Google Calendar, Gmail, Outlook | [App API](/code/apps/scheduling) |
| [Social](/code/apps/social) | [`noun:handle`](https://startupbuilder.dev/business/nouns/handle), [`noun:post`](https://startupbuilder.dev/business/nouns/post) | [`Post.publish`](/code/apps/social/publish), [`Post.schedule`](/code/apps/social/schedule), `Post.withdraw`, [`Handle.connect`](/code/integrations/calls/connect-handle), `Post.create` | LinkedIn, X account, Reddit, Hacker News, Product Hunt, YouTube, TikTok, Instagram, Facebook | [App API](/code/apps/social) |
| [Ads](/code/apps/ads) | [`noun:campaign`](https://startupbuilder.dev/business/nouns/campaign), [`noun:ad`](https://startupbuilder.dev/business/nouns/ad), [`noun:audience`](https://startupbuilder.dev/business/nouns/audience), [`noun:demand-budget`](https://startupbuilder.dev/business/nouns/demand-budget) | [`Campaign.create`](/code/apps/ads/create-campaign), [`Campaign.update`](/code/apps/ads/update-campaign), [`Ad.create`](/code/apps/ads/create-ad), [`Audience.create`](/code/apps/ads/create-audience), `Mandate.spend` | Meta Ads, Google Ads, Microsoft Ads, LinkedIn Ads, Reddit Ads, X Ads, TikTok Ads | [App API](/code/apps/ads) |
| [SEO](/code/apps/seo) | [`noun:keyword`](https://startupbuilder.dev/business/nouns/keyword), [`noun:page`](https://startupbuilder.dev/business/nouns/page), [`noun:monitor`](https://startupbuilder.dev/business/nouns/monitor), [`noun:domain`](https://startupbuilder.dev/business/nouns/domain) | [`Keyword.track`](/capabilities/measure/search-readout), `Keyword.create`, `Keyword.update`, `Monitor.update` | Google Search Console, Bing Webmaster, Google Analytics | [App API](/code/apps/seo) |
| [Sites and content](/code/apps/sites-and-content) | [`noun:site`](https://startupbuilder.dev/business/nouns/site), [`noun:page`](https://startupbuilder.dev/business/nouns/page), [`noun:content`](https://startupbuilder.dev/business/nouns/content), [`noun:domain`](https://startupbuilder.dev/business/nouns/domain) | `Content.draft`, `Content.publish`, `Site.publish`, `Page.create`, `Page.update` | Google Search Console, Bing Webmaster, Google Business Profile | [App API](/code/apps/sites-and-content) |
| [Media](/code/apps/media) | [`noun:video`](https://startupbuilder.dev/business/nouns/video), [`noun:file`](https://startupbuilder.dev/business/nouns/file), [`noun:voice`](https://startupbuilder.dev/business/nouns/voice) | `Video.draft`, `Video.finalize`, `File.generate`, `File.edit`, `Voice.clone` | YouTube, TikTok, Instagram | [App API](/code/apps/media) |
| [Forms and waitlists](/code/apps/forms-and-waitlists) | [`noun:form`](https://startupbuilder.dev/business/nouns/form), [`noun:waitlist`](https://startupbuilder.dev/business/nouns/waitlist), [`noun:visitor`](https://startupbuilder.dev/business/nouns/visitor) | `Waitlist.join`, `Waitlist.admit`, `Visitor.identify`, `Visitor.merge`, `Form.create` | Google Analytics | [App API](/code/apps/forms-and-waitlists) |
| [Analytics and experiments](/code/apps/analytics-and-experiments) | [`noun:visit`](https://startupbuilder.dev/business/nouns/visit), [`noun:metric`](https://startupbuilder.dev/business/nouns/metric), [`noun:experiment`](https://startupbuilder.dev/business/nouns/experiment), [`noun:hypothesis`](https://startupbuilder.dev/business/nouns/hypothesis), [`noun:dashboard`](https://startupbuilder.dev/business/nouns/dashboard) | [`Metric.query`](/code/apps/analytics-and-experiments/query), `Metric.watch`, `Experiment.start`, `Experiment.conclude`, `Dashboard.ask` | Google Analytics, Google Search Console | [App API](/code/apps/analytics-and-experiments) |

## Your sales apps are Software: the tool works
Headless SaaS is the hub's [Software](https://startupbuilder.dev/business/nouns/software) kind, delivered through the [Headless SaaS](https://startupbuilder.dev/products/templates/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](https://startupbuilder.dev/business/nouns/startup) inherits them, metered by the call.

Its promise is testable: every write is one record, one Event, on every interface. A [Workflow](/capabilities/how-calls-compose) (it promises its steps run) is Software too, so the Workflows live here.

## One record runs across every app
A [contact](https://startupbuilder.dev/business/nouns/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](https://startupbuilder.dev/business/nouns/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.

```ts
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](https://startupbuilder.dev/business/nouns/watch) delivers it to any agent that subscribes.

A [Trigger](https://startupbuilder.dev/business/nouns/trigger) can start a [Workflow](/capabilities/how-calls-compose#catalog) on it unchanged, and `Metric.query` reads it back as a trend. [Events and webhooks](/code/events) lists every one.

## Your accounts plug in three ways
Each call runs on market data, on your connected account, or through a [browser agent](/capabilities/agents#acts-as-you) where a site has no API. Ranked [Mappings](https://startupbuilder.dev/business/nouns/mapping) choose the way, never the caller, and one [standing approval](https://startupbuilder.dev/business/nouns/mandate) bounds all three.

## Every send passes one check before it leaves
Before any message, post or enrollment goes out, the platform reads [Consent](https://startupbuilder.dev/business/nouns/consent), every [Suppression](https://startupbuilder.dev/business/nouns/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](/code/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](/code/integrations/your-crm), and your agents call the same Verbs either way.

The hub's [integrations](https://startupbuilder.dev/systems/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](https://startupbuilder.dev/business/nouns/dashboard), and `Dashboard.schedule` sends it every Monday.

[Analytics and experiments](/code/apps/analytics-and-experiments) holds the numbers behind it, so a chart and an agent read the same [Metric](https://startupbuilder.dev/business/nouns/metric).