Last Thursday an agency owner texted me a screenshot. His client — a plumbing franchise with 8 locations — had just asked for "the full picture" on their pay-per-call spend. The agency's existing report showed calls. Just calls. 847 calls last month, here's a graph, done.
The client wanted to know which of those 847 calls turned into booked jobs. Which sources produced callers who actually showed up. Which campaigns were generating $400 average tickets versus $1,200 emergency dispatch tickets.
The agency didn't have that report. They'd been sending call counts for six months.
I don't blame them — most agency reporting stops at call volume because that's where most tracking platforms stop. Honestly, I've sent reports like that too. We all have. But clients paying $15K/month for lead gen deserve to see what happened after the phone rang. This tutorial covers how to build that call conversion funnel report: impression to call to billable to closed, broken down by source, formatted for client decks. If you're still troubleshooting why your pay-per-call campaigns are bleeding money, fix those leaks first — then come back here to build the reporting layer.
Prerequisites
- Access to your call tracking platform (VeloCalls, Ringba, CallRail, or similar)
- Ad platform access for impression and click data (Google Ads, Facebook, Microsoft Ads)
- Client CRM access or a closed-deal feed (even a spreadsheet works)
- A spreadsheet tool for the initial build (Google Sheets is fine)
- Basic familiarity with call attribution — see our call attribution explainer if you need a refresher
Step 1: Define Your Funnel Stages
Before you pull data, agree on what you're measuring. Funnel definitions vary by vertical and client, but here's the framework that works across most pay-per-call campaigns.
Stage 1: Impressions. How many times your ads or landing pages were shown. This is top-of-funnel volume — the universe of potential leads who saw your client's message. Pull from ad platforms directly.
Stage 2: Clicks/Sessions. Users who engaged. For paid search, this is clicks. For organic or content, it's sessions. This stage measures intent — people who cared enough to do something.
Stage 3: Calls. Total phone calls generated. All of them — answered, unanswered, spam, wrong numbers, everything. This is raw volume before any qualification.
Stage 4: Connected Calls. Calls where someone picked up and stayed on the line past your duration threshold (usually 30 seconds for home services, 60-90 seconds for legal). This filters out immediate hangups and voicemails. Our IVR abandonment rate study shows exactly where callers drop off — useful context when you're explaining these numbers to clients.
Stage 5: Billable Calls. Calls that met your pay-per-call criteria — connected, qualified, in service area, during business hours, whatever your contract specifies. This is what the client pays for.
Stage 6: Booked/Quoted. Calls that resulted in a scheduled appointment, a quote delivered, or a case opened. This requires CRM data or client feedback.
Stage 7: Closed Revenue. Actual dollars collected. Jobs completed and paid, settlements funded, policies bound. The number your client actually cares about.
Not every report needs all seven stages. For a new client where you don't have CRM access yet, stages 1-5 are still valuable. Push as far down the funnel as your data allows. A report that stops at "billable calls" is better than one that stops at "calls." A report that reaches "closed revenue" is what keeps clients for years.
Will clients actually give you revenue data? Sometimes. Getting CRM access can feel like asking for their firstborn — I've had clients ghost me after the ask. But the ones who share? Those relationships stick. For verticals like home services pay-per-call, the math is especially clear because ticket values are predictable.
Step 2: Pull Source-Level Data From Your Ad Platforms
Start at the top of the funnel. You need impressions and clicks broken out by the dimensions that matter to your client.
For Google Ads:
- Export by Campaign (minimum), or by Ad Group if campaigns are broad
- Include: Impressions, Clicks, Cost, and any conversion events you're tracking
- Date range: match your reporting period exactly
For Facebook/Instagram Ads:
- Export by Campaign or Ad Set
- Include: Impressions, Link Clicks (not all clicks), Amount Spent
- Note: FB's "Calls" metric tracks click-to-call, not actual completed calls — you need your call platform for that
For Microsoft Ads:
- Same structure as Google: Campaign, Impressions, Clicks, Cost
- Don't forget to pull this if you're running any Bing traffic — clients forget they approved it, then wonder where those calls came from
For Organic/Direct:
- Pull from Google Analytics or JustAnalytics if you're using it
- Sessions by Source/Medium
- Filter to landing pages that include phone CTAs
Export to a master spreadsheet. I know — you want to build this in a dashboard tool. You will, later. For the first build, use a spreadsheet. It's easier to debug and iterate when you can see every formula.
Your spreadsheet should have one row per source (campaign or ad group level, depending on granularity), with columns for: Source Name, Impressions, Clicks, Spend. That's your baseline.
Step 3: Map Call Data to Sources
This is where most agency reporting breaks down. The call platform knows about calls. The ad platform knows about impressions. You have to connect them.
If you're using dynamic number insertion (DNI):
Your call platform assigns different tracking numbers to different traffic sources. Each call arrives tagged with its source. Export from your call platform with: Tracking Number, Source/Campaign Tag, Call Timestamp, Duration, Disposition (if available).
In VeloCalls, this export is in the Analytics section — filter by date range, export to CSV, and the source attribution travels with each call record. Ringba works similarly; CallRail's export is under Call Log > Export.
If you're using offline call tracking:
You're matching calls to sources manually or by timestamp proximity. Painful. Honestly kind of miserable. If you're still doing this, switch to DNI. Seriously. The dynamic number insertion explainer covers setup.
Join the data:
In your spreadsheet, create a VLOOKUP (or XLOOKUP, or whatever your tool supports) that matches source names between your ad platform export and your call export. You want a row that shows: Source, Impressions, Clicks, Spend, Total Calls.
Check for orphan calls — calls that came in on tracking numbers that don't match any known source. This usually means a number got reused, a source wasn't tagged correctly, or direct-dial traffic hit a generic number. Track orphan volume separately; don't just ignore it. If orphan calls exceed 10% of total volume, something's broken in your attribution setup.
Step 4: Add Duration and Disposition Filters
Raw call counts lie. A source that generated 200 calls sounds great until you realize 140 of them were sub-10-second hangups.
Create filtered call counts:
- Connected Calls: Duration >= your threshold (30s, 60s, 90s — whatever matches your billing criteria)
- Billable Calls: Connected AND met all other criteria (geography, hours, qualification)
- Quality Calls: Billable AND disposition marked as "interested" or "appointment set" (if you're tagging dispositions)
Most call platforms let you filter the export directly. If not, add columns to your spreadsheet and filter in formulas.
Your funnel now shows: Source → Impressions → Clicks → Calls → Connected Calls → Billable Calls.
That's already more useful than 90% of agency call reports. But we're not done.
Calculate conversion rates at each stage:
| Metric | Formula |
|---|---|
| Click-to-Call Rate | Calls / Clicks |
| Call Connection Rate | Connected / Calls |
| Qualification Rate | Billable / Connected |
| Call-to-Billable | Billable / Calls |
These rates let you diagnose where each source breaks. A source with high click-to-call but low connection rate has a timing problem (calls outside business hours) or an IVR problem. A source with high connection but low qualification has a targeting problem — you're reaching people, they're just not the right people.
Step 5: Integrate CRM or Close Data
Here's where agency reports usually stop. Getting past billable calls requires data your call platform doesn't have.
Option 1: Client provides a closed-deal feed.
Best case. Client sends a weekly or monthly export: Lead Name/ID, Close Date, Revenue Amount, and ideally some kind of source tag or phone number you can match.
Match closed deals to your call records by:
- Phone number (most reliable if the CRM captures caller ANI)
- Timestamp proximity (fallback — risky if volume is high)
- Lead ID (if you're passing IDs into the CRM via webhook or integration)
For webhook integration with CRMs, our HubSpot integration guide and Salesforce integration guide cover the technical setup.
Option 2: Client provides aggregate close rates by source.
They can't give you deal-level data, but they can tell you "Google Ads leads close at 18%, Facebook at 12%." Apply those rates to your billable call counts to estimate closed revenue.
Be clear in the report: "Estimated closed revenue based on client-provided close rates." Don't pretend estimates are actuals. And if you're running AI voice qualification on top of pay-per-call, track those pre-qualification drops separately — they affect funnel math significantly.
Option 3: You estimate from industry benchmarks.
Last resort. Industry close rates for home services typically run 15-25% (higher for emergency, lower for estimates). Legal intake is 8-15% depending on case type. Insurance sits around 10-20% for qualified quotes.
Apply benchmark rates, but flag heavily: "Estimated closed revenue based on industry averages — actual may vary."
Your funnel now shows: Source → Impressions → Clicks → Calls → Connected → Billable → Booked (if available) → Closed Revenue.
That's the full picture.
Step 6: Calculate Source-Level Unit Economics
Now make it actionable. Clients don't just want to see the funnel — they want to know what each piece costs.
Key metrics per source:
| Metric | Formula | Why It Matters |
|---|---|---|
| Cost Per Call | Ad Spend / Total Calls | How much to generate any call |
| Cost Per Billable Call | Ad Spend / Billable Calls | True acquisition cost |
| Cost Per Close | Ad Spend / Closed Deals | What they're actually paying per customer |
| Revenue Per Billable Call | Closed Revenue / Billable Calls | Value generated per qualified interaction |
| ROAS | Closed Revenue / Ad Spend | The number that matters most |
Example breakout:
| Source | Spend | Billable Calls | Closes | Revenue | CPB | CPA | ROAS |
|---|---|---|---|---|---|---|---|
| Google - HVAC Emergency | $4,200 | 87 | 19 | $28,500 | $48 | $221 | 6.8x |
| Google - HVAC Repair | $3,100 | 102 | 14 | $11,200 | $30 | $221 | 3.6x |
| Facebook - Home Services | $1,800 | 34 | 4 | $4,800 | $53 | $450 | 2.7x |
That table tells a story. Emergency campaigns cost more per billable call but generate higher revenue per close. Facebook is underperforming on ROAS — maybe keep it for brand awareness, maybe cut it entirely. (My unpopular opinion: cut it. Most home services Facebook campaigns are vanity metrics. Fight me.) These are decisions the client can make. And if you're advising clients to comply with TCPA one-to-one consent requirements, flag which sources have proper consent records in your report — that's a compliance deliverable too.
If paid search is generating your traffic and you're worried about bot clicks eating budget before real callers arrive, ClickzProtect handles click fraud detection on the front end. The downstream funnel gets cleaner when the upstream traffic is verified.
Step 7: Format for Client Presentation
Data without design is a CSV. Clients deserve better.
Structure your report deck:
-
Executive Summary (1 slide): Total spend, total billable calls, total revenue, overall ROAS. One sentence on what improved, one on what needs attention.
-
Funnel Visualization (1 slide): A horizontal funnel graphic showing absolute numbers and conversion rates at each stage. Impressions → Clicks → Calls → Billable → Closes. Clients love funnel graphics. Give them one.
-
Source Breakdown (1-2 slides): The table from Step 6, formatted cleanly. Highlight best-performing source in green, worst in yellow. Don't make them hunt.
-
Trend Over Time (1 slide): Month-over-month or week-over-week on key metrics. Is ROAS improving? Are CPB costs rising? Show direction, not just snapshots.
-
Recommendations (1 slide): Based on the data, what should change? More budget to emergency campaigns? Kill the underperforming Facebook ad set? Test new keywords? Make it prescriptive.
Formatting rules:
- Use the client's brand colors if you have them
- Round percentages to one decimal place
- Currency to whole dollars for most metrics, cents only if precision matters
- Include date range on every page
- Add your agency logo and report date
Delivery format:
- PDF for the monthly send (people print these for meetings)
- Google Slides or live dashboard link for ongoing access
- Keep a folder structure:
/ClientName/Reports/2026-07/
Common Errors and How to Fix Them
Funnel math doesn't add up.
Calls exceed clicks. Billable exceeds connected. Something's off. Usually this means date range mismatches (ad platform set to different timezone), or attribution windows don't align (7-day click attribution vs same-day call attribution). Align time zones and pull all data for the same calendar window in UTC if you have to.
Source names don't match between platforms.
"Google Ads - HVAC" in your ad platform, "google-hvac" in your call platform. Create a mapping table — Source Raw → Source Standardized — and apply it before joining data. This is annoying. I've burned hours on this exact problem because someone named a campaign "HVAC_Emergency_v2_FINAL" in one place and "hvac emergency" in another. Do it once, update as new sources launch, and yell at whoever names campaigns without a standard.
Client doesn't believe the revenue numbers.
If you're using estimates, this is expected. Walk through the methodology. "We applied your stated 18% close rate to 102 billable calls, giving us 18 estimated closes at your $950 average ticket." The math should be transparent. If they disagree with the close rate, ask them for better data.
Report takes forever to build each month.
Your first report will take 3-4 hours. That's fine. But by month three, you should have templates and automated exports cutting this to under an hour. If you're still building from scratch monthly, invest in a reporting tool or proper spreadsheet automation. The Google Sheets call log export integration can automate the call data pull at least.
Next Steps
Automate the data pulls. Set up scheduled exports from your call platform and automated pulls from ad platforms via API or integrations. The goal is one-click refresh, not an hour of manual exports.
Add a live dashboard. Once the logic is stable, move to Looker Studio, Tableau, or whatever BI tool your agency standardizes on. Clients love logging in to see real-time numbers. It reduces "send me an update" emails by about 80%.
Segment deeper. Once you have the basic funnel, slice by more dimensions: day of week, time of day, device, landing page. Sources behave differently at 9am Monday versus 8pm Saturday. The real-time analytics guide covers dashboard configurations for these views.
Close the loop on revenue. Push for actual CRM access instead of client-provided feeds. Direct integration means less lag, less manual matching, and reports that are always current. Most CRMs support read-only access — if your client hesitates, pitch it as "we can generate reports without bothering your team."
Building the report is step one. The ongoing work is making it faster, making it more accurate, and making it so good that your client can't imagine getting this level of visibility from anyone else.
That's the retention play. And yeah, it's more work than just sending call counts. But the agencies still sending call counts in 2026 aren't going to keep those clients much longer.
Frequently Asked Questions
How often should I update call conversion funnel reports for clients?
Weekly for active campaigns, monthly for maintenance accounts. Weekly lets you catch problems before they compound — a traffic source that stopped converting last Tuesday is fixable if you see it Friday, but a month later your client's already frustrated. Monthly works for stable accounts where nothing changes fast, but even then, send a "no changes" update so clients know you're watching.
What's the minimum data I need to build an accurate funnel report?
At minimum: impression counts by source, call counts by source (with timestamps), billable call flags, and closed revenue when available. If you're missing closed revenue from your client, estimate from industry close rates (15-25% for home services, 8-12% for legal intake) and mark estimates clearly. A directionally correct estimate is better than leaving the revenue column blank.
Should I include call recordings in client reports?
Include excerpts or summaries for call quality discussions — never bulk recordings. Compliance gets messy with full recordings (consent laws vary by state), and frankly, clients won't listen to 47 calls. Summarize: "Of 52 billable calls this week, 38 reached decision-maker, 9 went to voicemail, 5 were wrong numbers despite passing IVR." That's actionable. A Dropbox link to 52 MP3s isn't.
How do I handle attribution when the same caller calls multiple times?
First-touch attribution for the initial call (credit goes to whatever source first brought them in), but flag repeat callers in your funnel. A source generating 40% repeat callers might look like it's producing volume when it's actually just the same 15 people calling back. Dedupe by caller ID or by lead record, depending on how your CRM tracks them, and show both raw and deduplicated counts.
Try VeloCalls for Your Vertical
Pay-per-call platform built for HVAC, plumbing, roofing, PI lawyers, Medicare brokers, and insurance. Smart routing, real-time bidding, visual IVR builder, AI conversation intelligence (transcription, sentiment, summaries). Per-minute pricing — Managed starts at 4¢/min, BYOC at 2¢/min, both drop as you scale.