Skip to content

Contacts, companies and deals

Business Studio’s CRM is not a separate product. A contact, a company and a deal are three kinds of card on the same board as everything else — filed, tagged, searched and moved the way every other card is — with three things the other kinds do not have: they are shared with your whole organisation, a deal moves along a sales pipeline instead of the four-column board, and every one of them carries a timeline and linked records.

The design decision behind this (build on the board rather than adopt a standalone CRM) is recorded in the repository under tasks/spike-crm-build-vs-adopt.md.

Most cards are private to whoever created them. A contact, a company or a deal is visible to every member of the organisation: a colleague sees the person you filed, can log a call on them, and can link them to a deal of their own. Their plain tasks stay theirs, and yours stay yours — a colleague’s private card reads as “Card not found”, exactly like a missing one.

Identity is shared too. A person is keyed on their LinkedIn profile, then their email, then their phone; a company on its domain (read from the website you give) or its LinkedIn page. Two people in the organisation filing the same person or company land on one card, whichever of them got there first.

KindTitle isStructured fieldsEnters at
Contactthe person’s namefirst/last name, email, phone, company (a label), role, LinkedIn profile, location, summarycaptured; Look up on LinkedIn fills the empty fields and writes what it found to the timeline
Companythe organisation’s namedomain, website, industry, size, location, LinkedIn company page, summarycaptured (no lookup yet)
Dealthe opportunityamount, currency, expected close date, company (a label)new on the pipeline

A contact’s company text is a display label. The real relation — which company card a contact or a deal belongs to — is a link (below), so a company page can list its people and its deals, and a contact can move employer without editing anyone’s deal.

Create them from Sales & CRM in the sidebar (Contacts, Companies, Deals), from the + Create button, by converting a plain task on its card (a task that turns out to be a person, a company or an opportunity), or from the API and the Claude connector.

Open Deals and the board draws the pipeline as columns: New → Qualified → Proposal → Won, with Lost behind the Archived toggle. Drag a deal between columns, or pick the stage on its card; the stage is validated (a value the pipeline does not know is refused with the real options) and the card’s board column follows it — won files under Done, lost under Archived. Every stage move is written to the deal’s timeline as a stage change, with who moved it and from where.

Each column header shows the total amount of the deals in it when they share one currency. ?columns=spine on the board URL shows deals on the ordinary four-column board instead.

Every contact, company and deal has a timeline beneath its card: notes, calls, meetings and emails you log; stage changes; and the result of each Look up on LinkedIn run, with what was found, which fields it filled, and its confidence. Entries are append-only — an audit trail that can be edited is not one — and the newest is first.

Suggest next step asks the assistant for the one most useful next action on this record, grounded in the card and its last ten timeline entries. The answer lands on the timeline as a system entry a few seconds later. It needs a connected AI channel; without one the button says so instead of pretending.

Three typed relations, all from the card’s Linked records section:

  • Company of — a contact or a deal belongs to a company.
  • Contact on this deal — a person is party to a deal.
  • Contact of — any card is about a person (a support thread, a task).

Both directions show on both cards, and a link that does not make sense (a company as a deal’s contact, say) is refused before it is written.

The board’s search box reaches the CRM fields, not only titles: type an email address, a phone number, a company name or a domain and the matching contact, deal or company comes up.

All routes are session- or API-key-authenticated and org-scoped.

RouteWhat it does
POST /api/tasks/contactsFile a person; returns the existing card (200) when the identity is already known
POST /api/tasks/companiesFile an organisation; same idempotency, keyed on domain or LinkedIn page
POST /api/tasks with destination: { scheme: "sales" }File a deal; optional subStatus (a pipeline stage, validated)
PATCH /api/tasks/:id with subStatusMove a deal; the board status is derived from the stage
PATCH /api/tasks/:id with payload: { contact | company | deal }Set the structured fields
GET / POST /api/tasks/:id/activitiesRead or log the timeline (kind: note, call, meeting, email)
GET / POST / DELETE /api/tasks/:id/linksRead, add or remove a typed link
POST /api/tasks/:id/next-actionAsk for the next step; 202 with the run id, 409 with the remedy when no AI channel is connected
GET /api/tasks?search=…&entity=contactSearch; every CRM row carries lastActivityAt

The SDK mirrors them on platformClient.tasks: createDeal, updateDeal, createCompany, listActivities, logActivity, listLinks, link, unlink, suggestNextAction.

Through the Claude connector, Claude works the CRM the way you do: create_task files a contact or a company, search_contacts finds a person by email, phone, company or name, log_activity remembers a call or a meeting on a card, link_records puts a contact at a company or on a deal, update_task moves a deal along the pipeline or sets its amount, and get_task reads a CRM card with its timeline and links in one call.

  • A lookup run for companies (the card’s lifecycle already reserves the state for it).
  • Capturing a contact from a social comment — a commenter has no email or profile to key on.
  • Calendar sync, custom fields and saved views.