Skip to main content
Authenticated API

This endpoint requires a valid JWT Bearer token. Accessible via the API gateway at /v1/commerce/*.

CRM API

Customer relationship management for contacts, leads, engagement tracking, and sales pipeline.

Authentication Required

All endpoints require a valid Bearer token. See Authentication for details.

Overview

AttributeValue
Base Path/api/v1/crm
AuthenticationBearer Token
Required Rolesmarketing, sales, manager, restaurant_manager, tenant_admin, platform_admin, system_admin, super_admin

Contacts

List Contacts

Retrieve CRM contacts.

GET /api/v1/crm/contacts

Query Parameters

ParameterTypeDescription
statusstringactive, inactive, lead, customer
segmentstringFilter by segment
sourcestringAcquisition source
searchstringSearch name/email
pageintegerPage number
limitintegerResults per page

Response

{
"data": [
{
"id": "contact_001",
"type": "customer",
"name": "John Smith",
"email": "john@example.com",
"phone": "+1234567890",
"company": "Acme Corp",
"title": "Director of Operations",
"source": "website",
"status": "active",
"score": 85,
"tags": ["enterprise", "high_value"],
"custom_fields": {
"industry": "technology",
"company_size": "500+"
},
"engagement": {
"last_interaction": "2026-01-24T15:00:00Z",
"total_interactions": 45,
"lifetime_value": 12500.00
},
"owner": {
"id": "user_001",
"name": "Sales Rep Mike"
},
"created_at": "2025-06-01T00:00:00Z"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 1250
}
}

Create Contact

POST /api/v1/crm/contacts

Request Body

{
"name": "Jane Doe",
"email": "jane@example.com",
"phone": "+1234567890",
"company": "Tech Corp",
"title": "VP of Food Services",
"source": "referral",
"type": "lead",
"tags": ["enterprise"],
"custom_fields": {
"industry": "healthcare",
"locations": 25
},
"owner_id": "user_001",
"notes": "Interested in multi-location deployment"
}

Get Contact

GET /api/v1/crm/contacts/{contact_id}

Response

{
"id": "contact_001",
"type": "customer",
"name": "John Smith",
"email": "john@example.com",
"phone": "+1234567890",
"company": "Acme Corp",
"title": "Director of Operations",
"address": {
"street": "123 Business Ave",
"city": "San Francisco",
"state": "CA",
"zip": "94105"
},
"social": {
"linkedin": "https://linkedin.com/in/johnsmith",
"twitter": "@johnsmith"
},
"score": 85,
"score_breakdown": {
"engagement": 25,
"profile_completeness": 20,
"recent_activity": 25,
"fit_score": 15
},
"deals": [
{
"id": "deal_001",
"name": "Enterprise License",
"value": 50000.00,
"stage": "negotiation"
}
],
"activities": [
{
"type": "email_opened",
"timestamp": "2026-01-24T15:00:00Z",
"details": "Opened pricing email"
}
],
"notes": [
{
"id": "note_001",
"content": "Very interested in drive-thru voice AI",
"created_by": "user_001",
"created_at": "2026-01-20T10:00:00Z"
}
]
}

Update Contact

PUT /api/v1/crm/contacts/{contact_id}

Delete Contact

DELETE /api/v1/crm/contacts/{contact_id}

Merge Contacts

Irreversible Operation

Merging contacts permanently combines records into the primary contact. The merged contacts are deleted and cannot be recovered. Review field preferences carefully before merging.

Merge duplicate contacts.

POST /api/v1/crm/contacts/merge

Request Body

{
"primary_contact_id": "contact_001",
"merge_contact_ids": ["contact_002", "contact_003"],
"field_preferences": {
"email": "contact_001",
"phone": "contact_002"
}
}

Lead Scoring

Get Lead Score

GET /api/v1/crm/contacts/{contact_id}/score

Response

{
"contact_id": "contact_001",
"total_score": 85,
"grade": "A",
"breakdown": {
"demographic": {
"score": 25,
"max": 30,
"factors": [
{"factor": "company_size", "score": 10, "reason": "500+ employees"},
{"factor": "industry", "score": 8, "reason": "Technology sector"},
{"factor": "title", "score": 7, "reason": "Director level"}
]
},
"behavioral": {
"score": 35,
"max": 40,
"factors": [
{"factor": "email_engagement", "score": 12, "reason": "High open rate"},
{"factor": "website_visits", "score": 10, "reason": "15 visits this month"},
{"factor": "content_downloads", "score": 8, "reason": "Downloaded pricing guide"},
{"factor": "demo_request", "score": 5, "reason": "Requested demo"}
]
},
"fit": {
"score": 25,
"max": 30,
"factors": [
{"factor": "budget", "score": 10, "reason": "Enterprise budget"},
{"factor": "need", "score": 8, "reason": "Active pain points"},
{"factor": "timeline", "score": 7, "reason": "Q1 decision"}
]
}
},
"recommendation": "Sales ready - schedule call",
"updated_at": "2026-01-24T19:00:00Z"
}

Configure Scoring Rules

PUT /api/v1/crm/scoring/rules

Request Body

{
"rules": [
{
"category": "demographic",
"field": "company_size",
"conditions": [
{"operator": "gte", "value": 500, "score": 10},
{"operator": "gte", "value": 100, "score": 7},
{"operator": "gte", "value": 50, "score": 5}
]
},
{
"category": "behavioral",
"event": "demo_request",
"score": 15
}
]
}

Data Enrichment

Enrich Contact

Enrich contact with external data.

POST /api/v1/crm/contacts/{contact_id}/enrich

Response

{
"contact_id": "contact_001",
"enrichment_status": "completed",
"data_added": {
"company": {
"employees": 850,
"revenue": "$50M-$100M",
"industry": "Technology",
"founded": 2010,
"website": "https://acmecorp.com"
},
"social": {
"linkedin": "https://linkedin.com/in/johnsmith",
"linkedin_connections": 500
},
"contact": {
"verified_email": true,
"phone_type": "mobile"
}
},
"confidence": 0.92,
"sources": ["clearbit", "linkedin", "email_verification"]
}

Bulk Enrich

POST /api/v1/crm/contacts/enrich/bulk

Request Body

{
"contact_ids": ["contact_001", "contact_002", "contact_003"],
"fields": ["company", "social", "email_verification"]
}

Deals & Pipeline

List Deals

GET /api/v1/crm/deals

Query Parameters

ParameterTypeDescription
stagestringFilter by stage
owner_idstringFilter by owner
min_valuenumberMinimum deal value
close_datedateExpected close date

Response

{
"data": [
{
"id": "deal_001",
"name": "Acme Corp Enterprise License",
"contact_id": "contact_001",
"company": "Acme Corp",
"value": 50000.00,
"currency": "USD",
"stage": "negotiation",
"probability": 60,
"expected_close": "2026-02-15",
"owner": {
"id": "user_001",
"name": "Sales Rep Mike"
},
"products": [
{"name": "Enterprise License", "quantity": 1, "value": 45000.00},
{"name": "Implementation", "quantity": 1, "value": 5000.00}
],
"created_at": "2026-01-10T00:00:00Z",
"updated_at": "2026-01-24T15:00:00Z"
}
],
"pipeline_summary": {
"total_value": 450000.00,
"weighted_value": 285000.00,
"deal_count": 25
}
}

Deal Stages

StageDescription
leadInitial lead
qualifiedQualified opportunity
proposalProposal sent
negotiationIn negotiation
closed_wonDeal won
closed_lostDeal lost

Create Deal

POST /api/v1/crm/deals

Request Body

{
"name": "New Enterprise Deal",
"contact_id": "contact_001",
"value": 75000.00,
"stage": "qualified",
"expected_close": "2026-03-01",
"owner_id": "user_001",
"products": [
{"product_id": "prod_001", "quantity": 1}
],
"notes": "Multi-location deployment"
}

Update Deal Stage

PATCH /api/v1/crm/deals/{deal_id}/stage

Request Body

{
"stage": "proposal",
"notes": "Sent pricing proposal"
}

Get Pipeline Analytics

GET /api/v1/crm/pipeline/analytics

Response

{
"pipeline": {
"total_value": 450000.00,
"weighted_value": 285000.00,
"deal_count": 25,
"avg_deal_size": 18000.00
},
"by_stage": [
{"stage": "lead", "count": 8, "value": 120000.00},
{"stage": "qualified", "count": 6, "value": 90000.00},
{"stage": "proposal", "count": 5, "value": 100000.00},
{"stage": "negotiation", "count": 4, "value": 80000.00},
{"stage": "closed_won", "count": 2, "value": 60000.00}
],
"velocity": {
"avg_days_to_close": 45,
"avg_days_in_stage": {
"lead": 7,
"qualified": 10,
"proposal": 14,
"negotiation": 14
}
},
"forecast": {
"this_month": 85000.00,
"next_month": 125000.00,
"this_quarter": 350000.00
}
}

Activities

Log Activity

POST /api/v1/crm/activities

Request Body

{
"contact_id": "contact_001",
"deal_id": "deal_001",
"type": "call",
"subject": "Discovery Call",
"description": "Discussed pain points and requirements",
"outcome": "positive",
"duration_minutes": 30,
"next_steps": "Send proposal by Friday"
}

Activity Types

TypeDescription
callPhone call
emailEmail sent/received
meetingIn-person meeting
demoProduct demo
noteGeneral note
taskTask completed

List Activities

GET /api/v1/crm/activities

Query Parameters

ParameterTypeDescription
contact_idstringFilter by contact
deal_idstringFilter by deal
typestringActivity type
start_datedatePeriod start
end_datedatePeriod end

Tasks

Create Task

POST /api/v1/crm/tasks

Request Body

{
"title": "Follow up on proposal",
"description": "Check if they reviewed the pricing",
"contact_id": "contact_001",
"deal_id": "deal_001",
"due_date": "2026-01-26T10:00:00Z",
"priority": "high",
"assigned_to": "user_001"
}

List Tasks

GET /api/v1/crm/tasks

Query Parameters

ParameterTypeDescription
assigned_tostringFilter by assignee
statusstringpending, completed, overdue
prioritystringlow, medium, high

Complete Task

POST /api/v1/crm/tasks/{task_id}/complete

Bulk Operations

Bulk Update

POST /api/v1/crm/contacts/bulk-update

Request Body

{
"contact_ids": ["contact_001", "contact_002"],
"updates": {
"owner_id": "user_002",
"tags": {"add": ["enterprise"], "remove": ["small_business"]}
}
}

Bulk Import

POST /api/v1/crm/contacts/import

Request Body (multipart/form-data)

file: contacts.csv
mapping: {"name": "Full Name", "email": "Email Address"}
options: {"skip_duplicates": true, "source": "csv_import"}

Webhooks

EventDescription
crm.contact_createdNew contact added
crm.contact_updatedContact modified
crm.deal_createdNew deal created
crm.deal_stage_changedDeal moved stages
crm.deal_wonDeal closed won
crm.deal_lostDeal closed lost
crm.task_dueTask due soon
crm.score_changedLead score updated

Error Responses

StatusCodeDescription
400duplicate_contactContact already exists
400invalid_stageInvalid deal stage
404contact_not_foundContact ID not found
404deal_not_foundDeal ID not found
409merge_conflictCannot merge contacts

  • CRM Guide - CRM setup guide
  • Lead Scoring - Scoring configuration
  • Marketing API - Marketing integration