How to build Apollo.io prospecting dashboards in Metabase
Apollo.io is where your prospecting, enrichment, and email sequences live. Metabase is where you turn that activity into shared, trustworthy outbound dashboards. Apollo isn't a deal-pipeline CRM, so this guide focuses on the prospecting funnel, sequence performance, and data quality. It covers two complementary paths: a lightweight MCP + CLI route that pulls live data with the Apollo MCP server and loads a CSV into Metabase with the Metabase CLI for quick analysis, and a durable warehouse route for reporting people depend on.
How do you connect Apollo.io to Metabase?
Most teams combine both routes: use the Apollo MCP server and Metabase CLI route to pull live data and stand up a quick analysis, and the warehouse route for the outbound dashboards the team depends on.
Live data in, quick analysis out
Pair Apollo's official MCP server (to read live prospects, enrichment, and sequence status) with the Metabase CLI, whose upload command loads a CSV into Metabase as a ready-to-query table and model.
- Quick lookups like "which sequences have the best reply rate?"
- Loading an Apollo CSV export into Metabase in seconds
- Spot-checks and one-off analyses without a warehouse
- Great for exploration, not governed reporting
- The Apollo MCP acts with your account's permissions and consumes credits — avoid write actions
- CSV uploads are snapshots — refresh or move to the warehouse for history
Durable dashboards with history
Sync Apollo into a database or warehouse with the Apollo API, CSV exports, or a connector, then point Metabase at it.
- Prospecting-funnel and sequence dashboards the whole team relies on
- Reply-rate, meeting, and deliverability trends over time
- Joining outbound activity with pipeline and revenue from your CRM
- Requires a destination database and a sync to maintain
- You own the funnel-stage and outcome definitions and the refresh schedule
- Capture email events over time so rates don't drift as records update
What can you analyze from Apollo.io data in Metabase?
- Prospecting funnel — sourced → enrolled → contacted → replied → meeting
- Sequence performance — open, reply, and bounce rate by sequence and step
- Meetings booked — by rep, sequence, and segment
- Data quality — enrichment coverage, verified vs. risky emails, duplicates vs. CRM
- Rep activity — emails, calls, and tasks by rep and account
- Efficiency — credits used per booked meeting
Which Apollo.io dashboards should you build in Metabase?
Prospecting funnel
From sourced to booked.
- Contacts sourced and enrolled by week (line)
- Funnel: enrolled → contacted → replied → meeting (funnel)
- Meetings booked by rep (bar)
- Funnel conversion by segment (matrix)
Sequence performance
Which sequences and steps work.
- Open and reply rate by sequence (bar)
- Reply rate by step number (line)
- Bounce rate by sequence (number)
- Best send day and time (heatmap)
Data quality
How good the sourced data is.
- Enrichment coverage by field (bar)
- Verified vs. risky emails (number)
- Duplicate contacts vs. CRM (number)
- Credits used per booked meeting (number)
Activity
Effort and coverage across the team.
- Emails and calls by rep (bar)
- Tasks completed vs. due (number)
- Accounts touched this week (number)
- Response time to inbound replies (line)
How do you use the Apollo MCP server with the Metabase CLI?
Pair the Apollo MCP server with the Metabase CLI for fast, hands-on analysis. Apollo ships an official MCP server that searches prospects, pulls enrichment, and checks sequence status; the Metabase CLI's upload command loads a CSV into Metabase and creates a ready-to-query table and model.
Example workflow
- Ask the Apollo MCP which sequences have the best reply rate this month.
- Export the sequence or contact data you want to keep as a CSV.
- Run
mb upload csvto load it into Metabase as a table and model, then build questions and dashboards on top.
Be honest about the limits
- The Apollo MCP is great for live lookups — not for scheduled or audited outbound reporting.
- A CSV upload is a point-in-time snapshot; refresh it with
mb upload replaceor move to the warehouse for real history. - The Apollo MCP acts with the connected account's permissions and consumes credits — scope it to lookups.
mb upload csvneeds an uploads database configured under Admin → Settings → Uploads.
How do you set up the Apollo MCP server and the Metabase CLI?
Apollo MCPofficial
- Endpoint
https://mcp.apollo.io/mcp- Auth
- OAuth on first use
- Covers
- Prospecting, enrichment, leads, companies, sequences
Metabase CLIofficial
- Install
npm install -g @metabase/cli- Auth
mb auth login(browser OAuth on v62+, or an API key)- Load data
mb upload csv --file data.csv- Requires
- An uploads database (Admin → Settings → Uploads)
{
"mcpServers": {
"apollo": {
"url": "https://mcp.apollo.io/mcp"
}
}
}# Install the Metabase CLI
npm install -g @metabase/cli
# Log in (opens your browser; requires Metabase v62+)
mb auth login --url https://your-metabase.example.com
# Load an Apollo CSV export — creates a table AND a model
mb upload csv --file apollo-sequences.csv --collection root
# Refresh that same table later from a new export
mb upload replace <table-id> --file apollo-sequences.csvThe first request triggers Apollo's OAuth flow. Use the MCP for prospecting, enrichment, and sequence lookups — not for governed reporting, which should run on warehouse-backed Metabase models. The Metabase CLI stores its credentials securely after mb auth login.
Can you generate an Apollo dashboard with AI?
Yes. Use the prompt below with any assistant that can run the Apollo MCP server and the Metabase CLI. It works end to end: if Apollo tables already exist in Metabase it analyzes those; otherwise it pulls the data over the Apollo MCP, loads it with mb upload csv, then builds the dashboard — defining a consistent meeting-booked signal and skipping cards it has no data for.
Create a polished Metabase dashboard for Apollo.io prospecting analytics.
Work end to end: get the data into Metabase if it isn't there yet, then build.
Goal: Help SDR leaders understand the prospecting funnel, sequence performance,
data quality, and rep activity from Apollo.io data.
Step 1 — Find or load the data:
- First, check what already exists in Metabase (search for Apollo tables and
models). If durable Apollo data is already present — synced from a warehouse or
uploaded earlier — use it and skip to Step 2.
- If nothing is there, pull it with the Apollo MCP server: contacts, accounts,
sequences and steps, email events (sent/delivered/opened/replied/bounced),
calls, and tasks. Write each result to a CSV, then load it with the Metabase
CLI — run "mb upload csv --file <export>.csv" so each upload creates a table and
a ready-to-query model. Use "mb upload replace <table-id> --file <export>.csv"
to refresh an existing table instead of creating duplicates.
Step 2 — Inspect before querying:
Apollo CSV exports are usually flat and pre-aggregated (one row per contact or
sequence, with columns like reply rate, bounce rate, and meetings booked).
Warehouse tables are raw and event-grained (an email-events table with sent,
delivered, opened, replied, and bounced timestamps). Inspect the actual tables
and column names first; do not assume exact names or that an event-level table
exists.
Important:
- Build on whatever data is present; don't claim Metabase connects natively to
Apollo — it reads a database or CLI-uploaded tables.
- If the data already provides rates, chart them directly; only recompute open
and reply rates over the delivered (not sent) base when raw counts are
available, and track bounce rate separately.
- Count a "meeting booked" from a consistent signal (meeting task, calendar
event, or reply classified as positive) and state which one.
- Report rates with their denominators visible; small sequences look noisy.
- Only build a card if its underlying column/metric exists in the data.
- A single CSV is a point-in-time snapshot: only build trend cards if there is a
usable date column or multiple periods have been uploaded.
Dashboard title: Apollo Prospecting Overview
Sections:
1. Executive summary (KPI cards): Contacts enrolled; Reply rate; Meetings booked;
Bounce rate; Enrichment coverage; Credits per meeting.
2. Funnel: Enrolled → contacted → replied → meeting; conversion by segment.
3. Sequences: Open and reply rate by sequence; reply rate by step; bounce rate.
4. Data quality: Enrichment coverage by field; verified vs. risky emails;
duplicates vs. CRM.
5. Activity: Emails and calls by rep; tasks completed; accounts touched.
Filters: Sequence, Rep, Segment, Date range.
Reuse the models Metabase auto-created from uploaded CSVs, or (for a warehouse)
create reusable models: modeled_apollo_contacts, modeled_apollo_sequences,
modeled_apollo_email_events, modeled_apollo_calls, and modeled_apollo_tasks.
Output: Build the dashboard if you have permission; otherwise provide the exact
questions, SQL, model definitions, and layout. Include caveats for any metric
that cannot be calculated from the available data. Reconcile totals against
Apollo's own analytics. Keep it practical, dense, and executive-readable.How do you sync Apollo data into a database or warehouse?
For dashboards that need history and reliability, land Apollo data in a database first, then connect Metabase to that database.
Connector options
- Apollo API (raw) — pull contacts, accounts, sequences, email events, calls, and tasks; capture email events incrementally.
- dlt (code) — write a Python pipeline against the Apollo API for incremental loads.
- CSV / scheduled exports — for smaller teams, exports can land the core objects on a cadence.
Notes
- Land raw tables first, then build clean models on top.
- Capture email events over time (sent/delivered/opened/replied/bounced) so rates don't drift as records update.
- Keep a stable meeting-booked signal so funnel conversion is comparable across periods.
- De-duplicate contacts against your CRM to keep coverage honest.
How should you model Apollo data in Metabase?
Core tables
| Table | Grain | Key columns |
|---|---|---|
contacts | one row per contact | id, account_id, email, phone, title, enrolled_at, owner_id |
sequences | one row per sequence | id, name, status |
email_events | one row per email | id, contact_id, sequence_id, step_number, status, sent_at, opened_at, replied_at |
meetings | one row per booked meeting | id, contact_id, booked_at, owner_id |
calls / tasks | one row per activity | id, contact_id, owner_id, completed_at |
Modeling advice
- Build
modeled_apollo_email_eventswith clean status flags so open, reply, and bounce rates are unambiguous. - Define the funnel stages once (enrolled → contacted → replied → meeting) and reuse them.
- Track enrichment coverage as the share of contacts with a value in each key field.
- Join to your CRM's deals to connect outbound activity to pipeline created and won.
Which Apollo.io metrics should you track in Metabase?
| Metric | Definition | Notes |
|---|---|---|
| Reply rate | Replies ÷ delivered emails. | See reply rate. |
| Meetings booked | Distinct contacts with a booked meeting. | See meetings booked. |
| Bounce rate | Bounced ÷ sent emails. | See email bounce rate. |
| Funnel conversion | Rate between adjacent funnel stages. | Show denominators; small cohorts are noisy. |
| Enrichment coverage | Share of contacts with a value in a field. | Report per field (email, phone, title). |
| Credits per meeting | Credits used ÷ meetings booked. | An efficiency signal, not a target. |
What SQL powers Apollo.io dashboards in Metabase?
These assume the modeled tables above (PostgreSQL dialect). Adjust identifiers to match your warehouse.
Enrolled → contacted → replied → meeting over the last 90 days.
-- Prospecting funnel over the last 90 days
SELECT
COUNT(DISTINCT c.id) AS enrolled,
COUNT(DISTINCT e.contact_id) FILTER (WHERE e.status <> 'bounced') AS contacted,
COUNT(DISTINCT e.contact_id) FILTER (WHERE e.replied_at IS NOT NULL) AS replied,
COUNT(DISTINCT m.contact_id) AS meetings_booked
FROM modeled_apollo_contacts c
LEFT JOIN modeled_apollo_email_events e ON e.contact_id = c.id
LEFT JOIN modeled_apollo_meetings m ON m.contact_id = c.id
WHERE c.enrolled_at >= CURRENT_DATE - INTERVAL '90 days';Both based on delivered emails, so bounces don't distort them.
-- Open and reply rate by sequence (delivered as the base)
SELECT
s.name AS sequence,
COUNT(*) FILTER (WHERE e.status <> 'bounced') AS delivered,
ROUND(100.0 * COUNT(*) FILTER (WHERE e.opened_at IS NOT NULL)
/ NULLIF(COUNT(*) FILTER (WHERE e.status <> 'bounced'), 0), 1) AS open_rate_pct,
ROUND(100.0 * COUNT(*) FILTER (WHERE e.replied_at IS NOT NULL)
/ NULLIF(COUNT(*) FILTER (WHERE e.status <> 'bounced'), 0), 1) AS reply_rate_pct
FROM modeled_apollo_email_events e
JOIN modeled_apollo_sequences s ON s.id = e.sequence_id
WHERE e.sent_at >= CURRENT_DATE - INTERVAL '90 days'
GROUP BY s.name
ORDER BY delivered DESC;Share of contacts with an email, phone, and title.
-- Enrichment coverage by field
SELECT
COUNT(*) AS contacts,
ROUND(100.0 * COUNT(email) / COUNT(*), 1) AS pct_with_email,
ROUND(100.0 * COUNT(phone) / COUNT(*), 1) AS pct_with_phone,
ROUND(100.0 * COUNT(title) / COUNT(*), 1) AS pct_with_title
FROM modeled_apollo_contacts;