CRM
The CRM module manages leads, lead conversion, contacts, companies, deal stages, deals, invoices, payments, and basic accounting for agent-assisted sales and operations.
What it does
CRM is the app-plane module for customer, pipeline, and revenue state. It lets agents capture leads, convert qualified leads, create contacts and companies, use workspace-defined deal stages, create invoices with line items, record payments, and write balanced journal entries.
Core resources:
contactscompaniesleadslead_conversionsdeal_stagesdealsnotesinvoicespaymentsaccounting_accountsaccounting_journal_entries
Workspaces can use built-in deal stages or create custom stages such as discovery, proposal_sent, legal_review, won, and lost.
Resource model
All CRM resources are tenant-owned, workspace-scoped, and include shared app-plane fields such as tenant_id, workspace_id, created_at, updated_at, source, and last_agent_actor_id. Exposed CRM resources can use queryable custom_fields JSON for company segment, sales motion, campaign attribution, implementation risk, or finance metadata.
Leads:
| Field | Purpose |
|---|---|
id | Lead identifier. |
name | Person or opportunity name before conversion. |
email | Optional email address. |
company_name | Company name before a company record exists. |
source | manual, website, referral, campaign, import, api, mcp, or other. |
status | new, working, qualified, disqualified, or converted. |
custom_fields | Queryable workspace JSON. |
Contacts:
| Field | Purpose |
|---|---|
id | Contact identifier. |
name | Human-readable name. |
email | Optional email address. |
phone | Optional phone number. |
company_id | Optional linked company. |
company_name | Optional company name when a company record is not yet linked. |
Companies:
| Field | Purpose |
|---|---|
id | Company identifier. |
name | Company/account name. |
domain | Optional domain for matching. |
website | Optional website URL. |
Deals:
| Field | Purpose |
|---|---|
id | Deal identifier. |
name | Deal name. |
company_id | Optional linked company. |
contact_id | Optional linked contact. |
stage | Pipeline stage. |
amount_cents | Optional deal amount in minor units. |
currency | Currency code, default USD. |
custom_fields | Queryable workspace JSON. |
Invoices, payments, and accounting:
| Resource | Purpose |
|---|---|
invoices | Customer billing document linked to a contact, company, deal, or lead, with line items. |
payments | Recorded payment against an invoice or customer account. |
accounting_accounts | Basic chart of accounts for cash, revenue, receivables, liabilities, and expenses. |
accounting_journal_entries | Balanced debit and credit lines for accounting events. |
Lead to cash
A services company can model a lightweight lead-to-cash workflow without leaving the workspace:
create_leadfor an inbound website or campaign lead.convert_leadto create or link a contact, company, and optional deal.create_deal_stagefor workspace-specific stages like discovery, proposal, signed, or delivered.update_dealas the work moves through the pipeline.create_invoicewith line items for the signed work.record_paymentwhen the customer pays.create_journal_entrywith balanced debit and credit lines for cash, revenue, receivables, or adjustments.
Permissions
Use crm:read to list and search CRM resources. Use crm:write to create or update leads, contacts, companies, deal stages, deals, invoices, payments, accounting accounts, and journal entries.
Recommended first workflow scopes:
crm:read
crm:write
tasks:write
activity:write
Example workflow
Prompt:
Create a website lead for Priya at Northstar Studio, convert it into a contact and company, create a Website redesign deal in the Proposal Sent stage for $18,000, invoice the first milestone, record a $9,000 payment, and create the balanced journal entry.
Expected operations:
create_leadconvert_leadcreate_deal_stageif the stage does not existupdate_dealcreate_invoicerecord_paymentcreate_journal_entrylog_activity
Audit behavior
Every CRM write creates an audit event. For deal stage changes, audit entries should include before and after stage values so humans can inspect what an agent changed.
Important audit cases:
- New contact created through MCP.
- Company created from a prompt.
- Lead converted into contact, company, and deal records.
- Custom deal stage created or assigned.
- Deal opened with amount and stage.
- Deal moved to another stage.
- Invoice, payment, and balanced journal entry created.
- Write failed because of missing scope, validation, or tenant mismatch.
MCP tools
create_contact
Create a CRM contact in the current workspace.
- Required scopes
- crm:write
- API equivalent
- POST /v1/contacts
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Full display name for the contact. |
| string · email | No | Email address used for matching, follow-up, and deduplication. | |
| phone | string | No | Optional phone number in a user-provided format. |
| company_id | string | No | Existing Slab5 company ID to link the contact to. |
| company_name | string | No | Company name to record when no company ID is available yet. |
| notes | string | No | Optional free-form context about the relationship or source. |
| idempotency_key | string | No | Stable client-generated key that makes retries safe for this write. |
Additional properties are rejected.
Example input
{
"name": "Jane Doe",
"email": "jane@acme.com",
"company_name": "Acme Corp",
"idempotency_key": "contact_jane_doe_acme"
}Example response
{
"contact": {
"id": "con_123",
"name": "Jane Doe",
"email": "jane@acme.com",
"company_name": "Acme Corp"
},
"request_id": "req_123"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The idempotency key was reused with a different request body.
search_contacts
Search contacts by name, email, company, or free-text query.
- Required scopes
- crm:read
- API equivalent
- GET /v1/contacts
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| query | string | No | Free-text search across contact name, email, company, and notes. |
| company_id | string | No | Restrict results to contacts linked to this company. |
| limit | integer · min 1 · max 100 | No | Maximum number of contacts to return. |
| cursor | string | No | Opaque cursor from a previous response's next_cursor. |
Additional properties are rejected.
Example input
{
"query": "Acme Corp",
"limit": 10
}Example response
{
"contacts": [
{
"id": "con_123",
"name": "Jane Doe",
"email": "jane@acme.com"
}
],
"request_id": "req_124"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
create_company
Create a company account in the CRM module.
- Required scopes
- crm:write
- API equivalent
- POST /v1/companies
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Company or account display name. |
| domain | string | No | Primary company domain, such as acme.com. |
| website | string | No | Canonical website URL for the company. |
| notes | string | No | Optional free-form account context. |
| idempotency_key | string | No | Stable client-generated key that makes retries safe for this write. |
Additional properties are rejected.
Example input
{
"name": "Acme Corp",
"domain": "acme.com"
}Example response
{
"company": {
"id": "com_123",
"name": "Acme Corp",
"domain": "acme.com"
},
"request_id": "req_125"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The idempotency key was reused with a different request body.
search_companies
Search company accounts by name, domain, or free-text query.
- Required scopes
- crm:read
- API equivalent
- GET /v1/companies
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| query | string | No | Free-text search across company name, domain, website, and notes. |
| limit | integer · min 1 · max 100 | No | Maximum number of companies to return. |
| cursor | string | No | Opaque cursor from a previous response's next_cursor. |
Additional properties are rejected.
Example input
{
"query": "Acme",
"limit": 10
}Example response
{
"companies": [
{
"id": "com_123",
"name": "Acme Corp",
"domain": "acme.com"
}
],
"request_id": "req_126"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
create_lead
Create a CRM lead before it is converted into a contact, company, or deal.
- Required scopes
- crm:write
- API equivalent
- POST /v1/leads
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | No description yet. |
| string · email | No | No description yet. | |
| phone | string | No | No description yet. |
| company_name | string | No | No description yet. |
| title | string | No | No description yet. |
| source | string · manual | website | referral | campaign | import | api | mcp | other | No | No description yet. |
| score | integer · min 0 | No | No description yet. |
| custom_fields | object | No | User-defined queryable JSON fields. |
| idempotency_key | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"name": "Priya Shah",
"company_name": "Northstar Studio",
"source": "website"
}Example response
{
"lead": {
"id": "lead_123",
"name": "Priya Shah",
"status": "new"
},
"request_id": "req_200"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The idempotency key was reused with a different request body.
list_leads
List leads by status, source, search text, or custom field.
- Required scopes
- crm:read
- API equivalent
- GET /v1/leads
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| query | string | No | No description yet. |
| status | string · new | working | qualified | disqualified | converted | No | No description yet. |
| source | string · manual | website | referral | campaign | import | api | mcp | other | No | No description yet. |
| custom_field_key | string | No | No description yet. |
| custom_field_value | string | No | No description yet. |
| limit | integer · min 1 · max 100 | No | No description yet. |
| cursor | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"source": "website",
"limit": 10
}Example response
{
"leads": [
{
"id": "lead_123",
"name": "Priya Shah"
}
],
"request_id": "req_201"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
convert_lead
Convert a lead into contact, company, and optionally deal records.
- Required scopes
- crm:write
- API equivalent
- POST /v1/leads/{lead_id}/convert
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| lead_id | string | Yes | No description yet. |
| company_id | string | No | No description yet. |
| contact_id | string | No | No description yet. |
| create_deal | boolean | No | No description yet. |
| deal_name | string | No | No description yet. |
| stage_key | string | No | No description yet. |
| amount_cents | integer · min 0 | No | No description yet. |
| currency | string | No | No description yet. |
| conversion_reason | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"lead_id": "lead_123",
"create_deal": true,
"deal_name": "Website redesign"
}Example response
{
"lead": {
"id": "lead_123",
"status": "converted"
},
"request_id": "req_202"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The requested resource does not exist in this workspace.
create_deal_stage
Create a custom deal stage for the workspace pipeline.
- Required scopes
- crm:write
- API equivalent
- POST /v1/deal-stages
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| key | string | Yes | No description yet. |
| name | string | Yes | No description yet. |
| position | integer · min 0 | No | No description yet. |
| kind | string · open | won | lost | No | No description yet. |
| probability | integer · min 0 | No | No description yet. |
| color | string | No | No description yet. |
| custom_fields | object | No | No description yet. |
| idempotency_key | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"key": "discovery",
"name": "Discovery",
"position": 10
}Example response
{
"stage": {
"id": "stage_123",
"key": "discovery"
},
"request_id": "req_203"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The idempotency key was reused with a different request body.
list_deal_stages
List workspace deal stages, including custom stages.
- Required scopes
- crm:read
- API equivalent
- GET /v1/deal-stages
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| query | string | No | No description yet. |
| limit | integer · min 1 · max 100 | No | No description yet. |
| cursor | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"limit": 25
}Example response
{
"stages": [
{
"id": "stage_123",
"key": "discovery"
}
],
"request_id": "req_204"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
create_deal
Create a deal associated with a company or contact.
- Required scopes
- crm:write
- API equivalent
- POST /v1/deals
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Short deal name visible in the CRM pipeline. |
| company_id | string | No | Existing company ID associated with the opportunity. |
| contact_id | string | No | Existing contact ID associated with the opportunity. |
| stage | string | No | Built-in or custom pipeline stage key to assign when the deal is created. |
| stage_key | string | No | Preferred stage key field for built-in or custom stages. |
| amount_cents | integer · min 0 | No | Deal value in the smallest currency unit. |
| currency | string · default USD | No | ISO currency code for the deal amount. |
| custom_fields | object | No | User-defined queryable JSON fields. |
| idempotency_key | string | No | Stable client-generated key that makes retries safe for this write. |
Additional properties are rejected.
Example input
{
"name": "Pilot subscription",
"company_id": "com_123",
"stage": "qualified",
"amount_cents": 500000,
"currency": "USD"
}Example response
{
"deal": {
"id": "deal_123",
"name": "Pilot subscription",
"stage": "qualified"
},
"request_id": "req_127"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The requested resource does not exist in this workspace.
update_deal_stage
Move an existing deal to a new pipeline stage. Deprecated in favor of update_deal.
- Required scopes
- crm:write
- API equivalent
- PATCH /v1/deals/{deal_id}
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| deal_id | string | Yes | Deal ID to update. |
| stage | string · new | qualified | proposal | won | lost | Yes | Target pipeline stage. |
| dry_run | boolean · default false | No | Preview validation and audit effects without changing the deal. |
| idempotency_key | string | No | Stable client-generated key that makes retries safe for this write. |
Additional properties are rejected.
Example input
{
"deal_id": "deal_123",
"stage": "proposal"
}Example response
{
"deal": {
"id": "deal_123",
"stage": "proposal"
},
"request_id": "req_128"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The requested resource does not exist in this workspace.
update_deal
Update deal stage, amount, or currency.
- Required scopes
- crm:write
- API equivalent
- PATCH /v1/deals/{deal_id}
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| deal_id | string | Yes | Deal ID to update. |
| stage | string | No | Optional built-in or custom target pipeline stage key. |
| stage_key | string | No | Preferred stage key field for built-in or custom stages. |
| amount_cents | integer · min 0 | No | Optional deal value in the smallest currency unit. |
| currency | string | No | Optional ISO currency code for the deal amount. |
| custom_fields | object | No | User-defined queryable JSON fields. |
| idempotency_key | string | No | Stable client-generated key that makes retries safe for this write. |
Additional properties are rejected.
Example input
{
"deal_id": "deal_123",
"stage": "proposal",
"amount_cents": 750000,
"currency": "USD"
}Example response
{
"deal": {
"id": "deal_123",
"stage": "proposal",
"amount_cents": 750000,
"currency": "USD"
},
"request_id": "req_128"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The requested resource does not exist in this workspace.
create_invoice
Create an invoice with product or service line items.
- Required scopes
- crm:write
- API equivalent
- POST /v1/invoices
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| invoice_number | string | Yes | No description yet. |
| company_id | string | No | No description yet. |
| contact_id | string | No | No description yet. |
| deal_id | string | No | No description yet. |
| currency | string · default USD | No | No description yet. |
| due_date | string · date-time | No | No description yet. |
| line_items | array | Yes | No description yet. |
| custom_fields | object | No | No description yet. |
| idempotency_key | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"invoice_number": "INV-1001",
"line_items": [
{
"kind": "service",
"name": "Website redesign",
"unit_amount_cents": 500000
}
]
}Example response
{
"invoice": {
"id": "inv_123",
"invoice_number": "INV-1001"
},
"request_id": "req_205"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The requested resource does not exist in this workspace.
list_invoices
List invoices by status, customer, deal, or custom field.
- Required scopes
- crm:read
- API equivalent
- GET /v1/invoices
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| status | string | No | No description yet. |
| company_id | string | No | No description yet. |
| contact_id | string | No | No description yet. |
| deal_id | string | No | No description yet. |
| limit | integer · min 1 · max 100 | No | No description yet. |
| cursor | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"status": "sent",
"limit": 10
}Example response
{
"invoices": [
{
"id": "inv_123",
"status": "sent"
}
],
"request_id": "req_206"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
record_payment
Record a payment against an invoice.
- Required scopes
- crm:write
- API equivalent
- POST /v1/payments
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| invoice_id | string | No | No description yet. |
| amount_cents | integer · min 1 | Yes | No description yet. |
| currency | string | No | No description yet. |
| paid_at | string · date-time | No | No description yet. |
| provider | string | No | No description yet. |
| provider_reference_id | string | No | No description yet. |
| custom_fields | object | No | No description yet. |
| idempotency_key | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"invoice_id": "inv_123",
"amount_cents": 250000
}Example response
{
"payment": {
"id": "pay_123",
"amount_cents": 250000
},
"request_id": "req_207"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The requested resource does not exist in this workspace.
create_accounting_account
Create a basic chart-of-accounts account.
- Required scopes
- crm:write
- API equivalent
- POST /v1/accounting/accounts
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| code | string | Yes | No description yet. |
| name | string | Yes | No description yet. |
| type | string · asset | liability | equity | revenue | expense | Yes | No description yet. |
| description | string | No | No description yet. |
| custom_fields | object | No | No description yet. |
| idempotency_key | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"code": "4000",
"name": "Services revenue",
"type": "revenue"
}Example response
{
"account": {
"id": "acct_123",
"code": "4000"
},
"request_id": "req_208"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The idempotency key was reused with a different request body.
list_accounting_accounts
List chart-of-accounts records.
- Required scopes
- crm:read
- API equivalent
- GET /v1/accounting/accounts
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| type | string | No | No description yet. |
| query | string | No | No description yet. |
| limit | integer · min 1 · max 100 | No | No description yet. |
| cursor | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"type": "revenue"
}Example response
{
"accounts": [
{
"id": "acct_123",
"name": "Services revenue"
}
],
"request_id": "req_209"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
create_journal_entry
Create a balanced accounting journal entry.
- Required scopes
- crm:write
- API equivalent
- POST /v1/accounting/journal-entries
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| entry_number | string | No | No description yet. |
| status | string · draft | posted | No | No description yet. |
| memo | string | No | No description yet. |
| lines | array | Yes | No description yet. |
| custom_fields | object | No | No description yet. |
| idempotency_key | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"status": "posted",
"lines": [
{
"account_id": "acct_cash",
"debit_cents": 10000
},
{
"account_id": "acct_ar",
"credit_cents": 10000
}
]
}Example response
{
"journal_entry": {
"id": "je_123",
"status": "posted"
},
"request_id": "req_210"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
The requested resource does not exist in this workspace.
list_journal_entries
List accounting journal entries.
- Required scopes
- crm:read
- API equivalent
- GET /v1/accounting/journal-entries
Example prompt
Input schema
| Property | Type | Required | Description |
|---|---|---|---|
| status | string | No | No description yet. |
| query | string | No | No description yet. |
| limit | integer · min 1 · max 100 | No | No description yet. |
| cursor | string | No | No description yet. |
Additional properties are rejected.
Example input
{
"status": "posted"
}Example response
{
"journal_entries": [
{
"id": "je_123",
"status": "posted"
}
],
"request_id": "req_211"
}Common errors
The token does not include the scope required for this operation.
The request payload failed schema validation.
