CRM Reports Guide
Overview
CRM Reports provide the analytical layer over your customer relationship data. Four purpose-built report endpoints aggregate and structure data across leads, customers, activities, and open opportunities, giving revenue and operations teams a clear view of pipeline health, team performance, and customer acquisition patterns without needing to build queries manually.
Reports are read-only analytical views. They do not modify any records; they summarise existing CRM data within a specified time window. Each report accepts a period shorthand (7, 30, or 90 days from today) or explicit date_from/date_to parameters for custom ranges. All reports are scoped to the current tenant and respect the authenticated user's access level.
Report Types
| Report | Endpoint | Primary Question |
|---|---|---|
| Lead Conversion | GET /reports/lead-conversion | How many leads progressed through each funnel stage, and at what rate? |
| Customer Acquisition | GET /reports/customer-acquisition | How many new customers were acquired, through which channels, and at what value? |
| Activity Summary | GET /reports/activity-summary | Are activities being completed on time, and how is workload distributed across the team? |
| Sales Pipeline | GET /reports/sales-pipeline | What is the current pipeline value, how is it distributed by stage, and what does the forecast look like? |
API Endpoints
All report endpoints are under the base path /api/v1/crm/reports.
Authentication: Required (Bearer token) for all endpoints.
1. Lead Conversion Report
Analyses lead volume and conversion rates across the qualification funnel for a given period.
Endpoint: GET /api/v1/crm/reports/lead-conversion
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
period | integer | 30 | Preset window in days: 7, 30, or 90. Ignored if date_from/date_to are provided |
date_from | date (YYYY-MM-DD) | - | Start of custom date range |
date_to | date (YYYY-MM-DD) | - | End of custom date range |
Example Requests:
# Last 30 days (default)
GET /api/v1/crm/reports/lead-conversion
# Last 90 days
GET /api/v1/crm/reports/lead-conversion?period=90
# Custom range
GET /api/v1/crm/reports/lead-conversion?date_from=2025-10-01&date_to=2025-10-31Response (200 OK):
{
"success": true,
"message": "Lead conversion report generated successfully",
"data": {
"period": {
"from": "2025-10-01",
"to": "2025-10-31"
},
"funnel": {
"new": 120,
"contacted": 87,
"qualified": 45,
"converted": 18
},
"conversion_rates": {
"new_to_contacted": 0.725,
"contacted_to_qualified": 0.517,
"qualified_to_converted": 0.400,
"overall": 0.150
},
"trends": [
{ "date": "2025-10-01", "leads": 4, "converted": 1 },
{ "date": "2025-10-02", "leads": 3, "converted": 0 },
{ "date": "2025-10-03", "leads": 5, "converted": 2 }
]
},
"meta": {}
}Response Fields:
| Field | Description |
|---|---|
funnel | Counts of leads that reached each status within the period |
conversion_rates.new_to_contacted | Fraction of new leads that reached "contacted" |
conversion_rates.contacted_to_qualified | Fraction of contacted leads that reached "qualified" |
conversion_rates.qualified_to_converted | Fraction of qualified leads that converted |
conversion_rates.overall | End-to-end conversion rate from new to converted |
trends | Daily breakdown of leads created and converted for the period |
Funnel Stage Counts
Funnel counts represent leads that reached a given status during the period, not cumulative totals. A lead that entered "contacted" on day 1 and "qualified" on day 15 contributes to both contacted and qualified counts.
2. Customer Acquisition Report
Measures new customer acquisition volume, channel attribution, and customer lifetime value indicators for a given period.
Endpoint: GET /api/v1/crm/reports/customer-acquisition
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
period | integer | 30 | Preset window in days: 7, 30, or 90 |
date_from | date (YYYY-MM-DD) | - | Start of custom date range |
date_to | date (YYYY-MM-DD) | - | End of custom date range |
Example Requests:
# Last 30 days
GET /api/v1/crm/reports/customer-acquisition
# Last 7 days
GET /api/v1/crm/reports/customer-acquisition?period=7
# Specific quarter
GET /api/v1/crm/reports/customer-acquisition?date_from=2025-10-01&date_to=2025-12-31Response (200 OK):
{
"success": true,
"message": "Customer acquisition report generated successfully",
"data": {
"period": {
"from": "2025-10-01",
"to": "2025-10-31"
},
"total_new_customers": 18,
"by_channel": {
"website": 7,
"referral": 4,
"cold_outreach": 3,
"trade_show": 2,
"paid_search": 2
},
"high_value_customers": [
{
"id": "01hwcust00000000000000001",
"name": "TechCorp Inc",
"acquired_at": "2025-10-12T10:00:00Z",
"estimated_lifetime_value": 150000.00
},
{
"id": "01hwcust00000000000000002",
"name": "Global Retail Group",
"acquired_at": "2025-10-18T14:30:00Z",
"estimated_lifetime_value": 95000.00
}
],
"average_clv": 42300.00
},
"meta": {}
}Response Fields:
| Field | Description |
|---|---|
total_new_customers | Customers created (converted from leads) within the period |
by_channel | Acquisition count broken down by the originating lead source |
high_value_customers | Top customers acquired in the period, ordered by estimated lifetime value |
average_clv | Mean estimated lifetime value across all customers acquired in the period |
3. Activity Summary Report
Summarises activity completion rates, type distribution, and per-user workload for a given period.
Endpoint: GET /api/v1/crm/reports/activity-summary
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
period | integer | 30 | Preset window in days: 7, 30, or 90 |
Example Requests:
# Last 30 days
GET /api/v1/crm/reports/activity-summary
# Last week
GET /api/v1/crm/reports/activity-summary?period=7Response (200 OK):
{
"success": true,
"message": "Activity summary report generated successfully",
"data": {
"period_days": 30,
"total": 342,
"completed": 278,
"pending": 41,
"overdue": 23,
"completion_rate": 0.813,
"billable_hours": 186.5,
"by_type": {
"call": 124,
"email": 98,
"meeting": 67,
"task": 53
},
"by_user": [
{
"user_id": "01hwuser0000000000000001",
"user_name": "Jane Davis",
"total": 89,
"completed": 75,
"overdue": 4,
"completion_rate": 0.843
},
{
"user_id": "01hwuser0000000000000002",
"user_name": "John Smith",
"total": 76,
"completed": 61,
"overdue": 7,
"completion_rate": 0.803
}
]
},
"meta": {}
}Response Fields:
| Field | Description |
|---|---|
total | All activities scheduled within or carried into the period |
completed | Activities marked as complete |
pending | Activities not yet due |
overdue | Activities past their due date and not completed |
completion_rate | completed / total ratio |
billable_hours | Sum of duration for billable activities in the period |
by_type | Activity counts by type (call, email, meeting, task) |
by_user | Per-user breakdown with individual completion rates and overdue counts |
Overdue Activities
A high overdue count relative to total (above ~10%) is a signal that activity SLAs are not being met. Use the by_user breakdown to identify which team members need workload redistribution or coaching.
4. Sales Pipeline Report
Analyses the current open opportunity pipeline by stage, assigned user, and deal age, and projects revenue under three forecast scenarios.
Endpoint: GET /api/v1/crm/reports/sales-pipeline
Query Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
period | integer | 30 | Preset window in days: 7, 30, or 90. Determines the "created within period" filter for new pipeline entries |
Example Requests:
# Current pipeline snapshot (default 30-day window for new entries)
GET /api/v1/crm/reports/sales-pipeline
# Opportunities created in the last quarter
GET /api/v1/crm/reports/sales-pipeline?period=90Response (200 OK):
{
"success": true,
"message": "Sales pipeline report generated successfully",
"data": {
"period_days": 30,
"total_opportunities": 64,
"pipeline_value": 2840000.00,
"weighted_value": 1138500.00,
"average_deal_size": 44375.00,
"by_stage": {
"prospect": {
"count": 18,
"value": 540000.00,
"weighted_value": 81000.00
},
"proposal": {
"count": 22,
"value": 980000.00,
"weighted_value": 392000.00
},
"negotiation": {
"count": 15,
"value": 875000.00,
"weighted_value": 525000.00
},
"closing": {
"count": 9,
"value": 445000.00,
"weighted_value": 400500.00
}
},
"by_user": [
{
"user_id": "01hwuser0000000000000001",
"user_name": "Jane Davis",
"opportunities": 21,
"pipeline_value": 1050000.00,
"weighted_value": 412500.00
},
{
"user_id": "01hwuser0000000000000002",
"user_name": "John Smith",
"opportunities": 18,
"pipeline_value": 890000.00,
"weighted_value": 356000.00
}
],
"aging": {
"under_30_days": 29,
"30_to_60_days": 18,
"60_to_90_days": 11,
"over_90_days": 6
},
"forecast": {
"best_case": 2840000.00,
"most_likely": 1138500.00,
"worst_case": 712000.00
}
},
"meta": {}
}Response Fields:
| Field | Description |
|---|---|
total_opportunities | Count of open opportunities (excludes won and lost) |
pipeline_value | Sum of opportunity values at full deal size |
weighted_value | Sum of opportunity_value * probability across all open opportunities |
average_deal_size | pipeline_value / total_opportunities |
by_stage | Pipeline breakdown per stage with raw and probability-weighted values |
by_user | Per-rep pipeline value and weighted value |
aging | Opportunity counts grouped by days since creation |
forecast.best_case | Full pipeline value - assumes all opportunities close |
forecast.most_likely | Weighted pipeline value - uses probability-adjusted amounts |
forecast.worst_case | Conservative estimate based on late-stage, high-probability deals only |
Aging Buckets:
| Bucket | Days Since Creation |
|---|---|
under_30_days | 0–29 days |
30_to_60_days | 30–60 days |
60_to_90_days | 61–90 days |
over_90_days | 91+ days |
Aging Pipeline Risk
Opportunities in the over_90_days bucket have a significantly higher probability of going stale or being lost. Any opportunity in this bucket without recent activity should be reviewed by the assigned rep immediately.
Business Scenarios
Scenario 1: Monthly Executive Revenue Review
Context: A revenue leader needs to compile a monthly performance report covering pipeline health, acquisition, and team activity before a board presentation.
Workflow:
- Pull lead conversion for the month to show funnel efficiency
- Pull customer acquisition for the month to show net-new revenue
- Pull sales pipeline for the current state of open deals
- Compile weighted pipeline value as the headline forecast number
# 1. Lead funnel performance for October
GET /api/v1/crm/reports/lead-conversion?date_from=2025-10-01&date_to=2025-10-31
# 2. New customer acquisition for October
GET /api/v1/crm/reports/customer-acquisition?date_from=2025-10-01&date_to=2025-10-31
# 3. Current pipeline snapshot
GET /api/v1/crm/reports/sales-pipeline?period=90
# Key metrics to surface:
# - conversion_rates.overall from lead-conversion
# - total_new_customers and average_clv from customer-acquisition
# - weighted_value and forecast.most_likely from sales-pipelineThe three reports together give a full-funnel picture: leads entering at the top, customers exiting at the bottom, and revenue forecast from open deals in the middle.
Scenario 2: Sales Team Performance Review
Context: A sales manager wants to identify which reps are carrying their pipeline effectively and which need coaching before end of quarter.
Workflow:
- Pull the activity summary to check completion rates by user
- Pull the pipeline report and inspect the
by_userbreakdown - Cross-reference reps with high overdue activity rates against pipeline performance
- Schedule 1:1s with reps showing both low pipeline value and high overdue count
# 1. Activity completion by rep for last 30 days
GET /api/v1/crm/reports/activity-summary?period=30
# 2. Pipeline by rep
GET /api/v1/crm/reports/sales-pipeline?period=90
# Warning signals:
# - activity by_user.completion_rate < 0.75
# - pipeline by_user.weighted_value significantly below team average
# - aging.over_90_days count > 3 for a single repScenario 3: Channel Effectiveness and Budget Allocation
Context: A marketing team wants to understand which acquisition channels are producing the highest-value customers in order to reallocate budget for the next quarter.
Workflow:
- Pull customer acquisition for the last quarter
- Compare
by_channelcounts against channel spend from your marketing tools - Cross-reference with lead conversion to see which source produces the highest conversion rate
- Bring both data sets to the budget planning meeting
# Customer acquisition breakdown for Q4 2025
GET /api/v1/crm/reports/customer-acquisition?date_from=2025-10-01&date_to=2025-12-31
# Lead conversion for the same period to see source-level funnel efficiency
GET /api/v1/crm/reports/lead-conversion?date_from=2025-10-01&date_to=2025-12-31Channels with high by_channel count and high average_clv are the priority candidates for increased investment.
Best Practices
1. Use period Shorthand for Operational Dashboards
For live dashboards that refresh automatically (e.g., a sales operations screen that updates hourly), use the period parameter rather than hardcoded dates. ?period=30 always returns the trailing 30 days from today, so dashboards stay current without date calculation on the client side.
2. Use date_from/date_to for Historical Comparisons
When comparing performance across defined periods (e.g., Q3 vs Q4, or year-over-year), always use explicit date_from and date_to parameters. This ensures the comparison windows are fixed and repeatable regardless of when the report is run.
3. Treat forecast.most_likely as Your Primary Forecast Number
The pipeline report provides three forecast scenarios. For internal planning, forecast.most_likely (probability-weighted pipeline value) is the most reliable single number. Use forecast.best_case only for optimistic ceiling modelling and forecast.worst_case as a floor for cash flow planning.
4. Monitor aging.over_90_days Weekly
Deals that have been in the pipeline for more than 90 days without progressing are a leading indicator of pipeline bloat and inflated forecasts. Add a weekly check of this bucket to your sales meeting cadence, and apply a manual probability override or close any deal that cannot be justified at its current stage.
Integration Points
With Lead Management
The lead conversion report draws its funnel data from the same lead records managed through the leads API. Improving lead qualification processes (better scoring, faster follow-up, clearer BANT criteria) will be directly reflected in improvements to conversion_rates.overall. Refer to the Lead Management guide for lead lifecycle management.
With Opportunity Pipeline
The sales pipeline report is the analytical counterpart to the opportunity management workflow. Opportunities created and progressed through the pipeline API are the source of record for all pipeline report data. Refer to the Opportunity Pipeline guide for how to manage individual opportunities.
With Activity Management
The activity summary report aggregates data from all CRM activities. Maintaining a clean and up-to-date activity log (completing or rescheduling overdue items promptly) is what makes the activity report actionable. Refer to the Activity Management guide for managing activities.
With CRM Search
When a report surfaces a data point worth investigating further (e.g., a single rep with unusually low pipeline), use the CRM Search endpoints to drill into that rep's specific leads, contacts, and opportunities directly.
Troubleshooting
Report Returns Empty or Zero Counts
Symptom: A report returns 200 OK but all numeric fields are 0 or arrays are empty.
Possible Causes:
- The selected
periodor date range predates any data in the system - No CRM records have been created yet
- The authenticated user lacks permissions to view CRM data for the tenant
Solution:
- Confirm CRM records exist by running a basic list query:bash
GET /api/v1/crm/leads?per_page=5 - If records exist, try widening the period to
90days or using explicitdate_from/date_toparameters that span a known active range. - Verify the user's Bouncer role includes the
crm.reports.viewpermission.
forecast.most_likely Appears Inflated
Symptom: The weighted pipeline value (forecast.most_likely) seems unrealistically high compared to actual close rates.
Cause: Opportunity probability values have not been kept current as deals age. Older opportunities in early stages retain their initial probability (e.g., 25%) even though their realistic close probability has declined.
Solution:
- Review opportunities in the
aging.over_90_daysbucket:bashGET /api/v1/crm/reports/sales-pipeline?period=90 # Check aging.over_90_days count - For each stale opportunity, update the probability to reflect current deal reality via the opportunities API, or close it as lost.
- Establish a process where reps review and update opportunity probabilities at least once per month.
Related Documentation
- Lead Management Guide - Managing the lead lifecycle
- Lead Conversion Guide - Converting leads to customers
- Opportunity Pipeline Guide - Managing sales opportunities
- Activity Management Guide - Tracking CRM activities
- CRM Search Guide - Searching across CRM entities