# CRM

URL: /systems/crm · Id: `system:crm`

> CRM keeps the Contacts and Organizations a Startup knows, every Lead, and the Deals it pursues with them.

CRM is the record of every [Contact](/business/nouns/contact), [Organization](/business/nouns/organization), [Lead](/business/nouns/lead), [Deal](/business/nouns/deal) and [Customer](/business/nouns/customer) a [Startup](/business/nouns/startup) knows. Every [Message](/business/nouns/message), [Meeting](/business/nouns/meeting), [Invoice](/business/nouns/invoice) and [Conversation](/business/nouns/conversation) lands in the same database, so each record's timeline is complete with no logging.

## Summary
| Part | This System |
| --- | --- |
| Group | Sales |
| Status | Live |
| Shelf | Front: offered from a Startup’s first days |

You can ask:

- “Who are my best leads?”
- “Add this person as a lead”
- “Move the Harbor deal to proposal”
- “Merge these two contacts”
- “Which deals are stuck?”

## What you get
| Part | This System |
| --- | --- |
| Starts | On for every Startup at creation, with nothing to install. |
| Built from | [Database](/code/platform/capabilities/database), [Search](/code/platform/search), [Integrations](/code/platform/integrations), [AI gateway](/code/platform/ai-gateway), [Event streams](/code/platform/event-streams), [Enrichment](/systems/sales/enrichment) |

## Nouns it owns
| Noun | Definition |
| --- | --- |
| [Contact](/business/nouns/contact) | A Contact is a person or Agent a Startup knows by at least one address, where Consent to message them is recorded. |
| [Organization](/business/nouns/organization) | An Organization is an outside party as one Startup knows it, keyed by its domain, such as an employer or a vendor. |
| [Lead](/business/nouns/lead) | A Lead is a Contact who raised a hand, by joining a Waitlist, filling a Form, or replying, without accepting an Offer. |
| [Deal](/business/nouns/deal) | A Deal is a Startup’s pursuit of one buyer’s acceptance of one or more Offers, ending won or lost. |
| [Customer](/business/nouns/customer) | A Customer is a party that has accepted an Offer from a Startup at any price, including zero. |

## Verbs
| Verb | Object | Approval | Event |
| --- | --- | --- | --- |
| [Contact.create](/business/nouns/contact/create) | [Contact](/business/nouns/contact) | None | `Contact.created` |
| [Contact.enrich](/business/nouns/contact/enrich) | [Contact](/business/nouns/contact) | None | [`Contact.enriched`](/business/events/Contact.enriched) |
| [Organization.create](/business/nouns/organization/create) | [Organization](/business/nouns/organization) | None | `Organization.created` |
| [Lead.qualify](/business/nouns/lead/qualify) | [Lead](/business/nouns/lead) | None | [`Lead.qualified`](/business/events/Lead.qualified) |
| [Deal.propose](/business/nouns/deal/propose) | [Deal](/business/nouns/deal) | Asks first; waits 1 business hour | [`Deal.proposed`](/business/events/Deal.proposed) |
| [Deal.win](/business/nouns/deal/win) | [Deal](/business/nouns/deal) | None | [`Deal.won`](/business/events/Deal.won) |
| [Deal.lose](/business/nouns/deal/lose) | [Deal](/business/nouns/deal) | None | [`Deal.lost`](/business/events/Deal.lost) |
| [Lead.convert](/business/nouns/lead/convert) | [Lead](/business/nouns/lead) | None | [`Lead.converted`](/business/events/Lead.converted) |
| [Contact.merge](/business/nouns/contact/merge) | [Contact](/business/nouns/contact) | Asks first; waits 1 business hour | [`Contact.merged`](/business/events/Contact.merged) |
| [Organization.merge](/business/nouns/organization/merge) | [Organization](/business/nouns/organization) | Asks first; waits 1 business hour | [`Organization.merged`](/business/events/Organization.merged) |
| [Lead.assign](/business/nouns/lead/assign) | [Lead](/business/nouns/lead) | None | [`Lead.assigned`](/business/events/Lead.assigned) |
| [Deal.assign](/business/nouns/deal/assign) | [Deal](/business/nouns/deal) | None | [`Deal.assigned`](/business/events/Deal.assigned) |
| [Deal.advance](/business/nouns/deal/advance) | [Deal](/business/nouns/deal) | None | [`Deal.advanced`](/business/events/Deal.advanced) |

## Events
| Direction | Event | How |
| --- | --- | --- |
| Emits | `Contact.created` | By [Contact.create](/business/nouns/contact/create) |
| Emits | [`Contact.enriched`](/business/events/Contact.enriched) | By [Contact.enrich](/business/nouns/contact/enrich) |
| Emits | `Organization.created` | By [Organization.create](/business/nouns/organization/create) |
| Emits | [`Lead.qualified`](/business/events/Lead.qualified) | By [Lead.qualify](/business/nouns/lead/qualify) |
| Emits | [`Deal.proposed`](/business/events/Deal.proposed) | By [Deal.propose](/business/nouns/deal/propose) |
| Emits | [`Deal.won`](/business/events/Deal.won) | By [Deal.win](/business/nouns/deal/win) |
| Emits | [`Deal.lost`](/business/events/Deal.lost) | By [Deal.lose](/business/nouns/deal/lose) |
| Emits | [`Lead.converted`](/business/events/Lead.converted) | By [Lead.convert](/business/nouns/lead/convert) |
| Emits | [`Contact.merged`](/business/events/Contact.merged) | By [Contact.merge](/business/nouns/contact/merge) |
| Emits | [`Organization.merged`](/business/events/Organization.merged) | By [Organization.merge](/business/nouns/organization/merge) |
| Emits | [`Lead.assigned`](/business/events/Lead.assigned) | By [Lead.assign](/business/nouns/lead/assign) |
| Emits | [`Deal.assigned`](/business/events/Deal.assigned) | By [Deal.assign](/business/nouns/deal/assign) |
| Emits | [`Deal.advanced`](/business/events/Deal.advanced) | By [Deal.advance](/business/nouns/deal/advance) |
| Consumes | [`Offer.accepted`](/business/events/Offer.accepted) | Moves [Lead](/business/nouns/lead) to `converted` |
| Consumes | [`Customer.activated`](/business/events/Customer.activated) | Moves [Customer](/business/nouns/customer) to `activated` |
| Consumes | [`Subscription.unsubscribed`](/business/events/Subscription.unsubscribed) | Moves [Customer](/business/nouns/customer) to `churned` |
| Consumes | [`Subscription.pastDue`](/business/nouns/subscription#subscriptionpastdue) | Moves [Customer](/business/nouns/customer) to `atRisk` |
| Consumes | [`Dispute.opened`](/business/nouns/dispute#disputeopened) | Moves [Customer](/business/nouns/customer) to `atRisk` |
| Consumes | [`Invoice.collected`](/business/events/Invoice.collected) | Moves [Customer](/business/nouns/customer) to `activated` |
| Consumes | [`Offer.subscribed`](/business/events/Offer.subscribed) | Moves [Customer](/business/nouns/customer) to `wonBack` |
| Consumes | [`Order.placed`](/business/events/Order.placed) | Moves [Customer](/business/nouns/customer) to `wonBack` |

## States
The lifecycle of a [Lead](/business/nouns/lead):

| State | Meaning | Moves to |
| --- | --- | --- |
| `new` (first) | It raised a hand, and no Worker works it yet. | `working` by [Lead.assign](/business/nouns/lead/assign); `nurture` by [Lead.nurture](/business/nouns/lead/nurture); `disqualified` by [Lead.disqualify](/business/nouns/lead/disqualify); `converted` on [`Offer.accepted`](/business/events/Offer.accepted) when the Lead buys on its own |
| `working` | Its owner is in touch and owes the next step. | `converted` by [Lead.qualify](/business/nouns/lead/qualify); `converted` by [Lead.convert](/business/nouns/lead/convert); `nurture` by [Lead.nurture](/business/nouns/lead/nurture); `disqualified` by [Lead.disqualify](/business/nouns/lead/disqualify) |
| `nurture` | Not ready to buy: it is off its owner’s queue and hears from a Sequence until it raises a hand again. | `working` by [Lead.assign](/business/nouns/lead/assign); `disqualified` by [Lead.disqualify](/business/nouns/lead/disqualify) |
| `converted` | It fits an Offer: a Deal is open for it, or it bought on its own; the Customer record carries on. | None: it ends here. |
| `disqualified` | It fits no Offer, for the reason recorded; its Contact record stays. | None: it ends here. |

Its other Nouns with a lifecycle: [Customer](/business/nouns/customer).

## Who operates it
| Part | This System |
| --- | --- |
| Accountable | [Sales Lead](/agents/sales/sales-lead) |
| Team | [Sales Team](/agents/sales) |
| Seat | A role agent holds it until a Human is seated. |
| Autonomy | `supervised` |
| Also calls its Verbs | [Sales Engineer](/agents/sales/sales-engineer), [Prospector](/agents/sales/prospector) |

## Approvals and limits
| Verb | Rule | Detail |
| --- | --- | --- |
| [Deal.propose](/business/nouns/deal/propose) | A person says yes first | Waits 1 business hour |
| [Contact.merge](/business/nouns/contact/merge) | A person says yes first | Waits 1 business hour |
| [Organization.merge](/business/nouns/organization/merge) | A person says yes first | Waits 1 business hour |
| [Deal.propose](/business/nouns/deal/propose) | Limit for the [Sales Lead](/agents/sales/sales-lead) | $25,000 per call |
| [Deal.win](/business/nouns/deal/win) | Mandate `close-out` for the [Sales Lead](/agents/sales/sales-lead) | Marks a Deal won or lost when the buyer signs or says no. |
| [Deal.lose](/business/nouns/deal/lose) | Mandate `close-out` for the [Sales Lead](/agents/sales/sales-lead) | Marks a Deal won or lost when the buyer signs or says no. |

## Processes that use it
| Process | How it uses it |
| --- | --- |
| [Inbound sales](/workflows/processes/inbound-sales) | A step calls [Lead.qualify](/business/nouns/lead/qualify) |
| [Outbound](/workflows/processes/outbound) | A step calls [Lead.assign](/business/nouns/lead/assign) |

## Rail underneath
| Noun | Stripe object | Source of truth |
| --- | --- | --- |
| [Customer](/business/nouns/customer) | **Customer** (`customer`) | The source of truth is db.sb, and Stripe holds a copy written from it. |

## Views and dashboards
| View | Shows | Metrics |
| --- | --- | --- |
| Pipeline | Open Deals by stage, with the owner and the next step on each. | [Outside paid Orders](/agents/sales#outside-paid-orders) |
| The [Sales Lead](/agents/sales/sales-lead)’s view | The Metrics its accountable Role answers for. | [Paid listing conversion](/agents/sales#paid-listing-conversion) |

## Access
What each Access level may call here.

| Access level | May call |
| --- | --- |
| `owner` | Every Verb (36) |
| `admin` | All but 3 of 36: `Contact.merge`, `Deal.propose`, `Organization.merge` |
| `member` | All but 3 of 36: `Contact.merge`, `Deal.propose`, `Organization.merge` |
| `viewer` | Read only (10 of 36) |

## Import and export
None.

## Fees and pricing
None.

## Availability and limits
| Part | This System |
| --- | --- |
| Status | Live |

## Compliance notes
Every Contact keeps where it came from and its Consent; deciding who to contact stays the founder’s.

Controls it carries:

- [Log completeness](/systems/trust-and-governance/controls/log-completeness)
- [Boundary protection](/systems/trust-and-governance/controls/boundary-protection)
- [Append-only records](/systems/trust-and-governance/controls/append-only-records)
- [Upstream review](/systems/trust-and-governance/controls/upstream-review)
- [Point-in-time recovery](/systems/trust-and-governance/controls/point-in-time-recovery)
- [Processing definitions](/systems/trust-and-governance/controls/processing-definitions)

## Related Systems
- [Prospecting](/systems/prospecting)
- [Sequences](/systems/sequences)
- [Quotes](/systems/quotes)
- [Scheduling](/systems/scheduling)

## Example
```ts
// A clinic-software Startup gets a demo request from a six-clinic group.
import { $ } from 'startup-builder'

// The routing Policy picks the owner by ICP fit; no owner is named.
await $.Lead.assign({ lead: 'lead_8Kq2' })

// An assisted sale: the Lead becomes a Deal and keeps its Acquisition.
const { deal } = await $.Lead.convert({ lead: 'lead_8Kq2', offer: 'offer_clinic_annual', route: 'deal' })

// Refused, naming each empty field, until the proposal stage's required fields are filled.
await $.Deal.advance({ deal: deal!.$id, stage: 'proposal' })

// The same buyer wrote in from a second address; the merge keeps every Message and Event.
await $.Contact.merge({ contact: 'contact_dup_41', into: 'contact_7Hn3' })
```