Docs Home Beam MCP APIs

Analytics API

Campaign performance metrics for connected tools

Campaign Performance Analytics

The Analytics API exposes campaign performance statistics, date-grained trends, report read models, lead-level rollups, and lead activity using your Organization API Key.

Lifetime campaign totals

Use GET /api/v1/campaigns/{campaign_id}/analytics for the existing no-date-filter campaign summary.

Date-scoped campaign trends

Query /analytics/timeseries?filter[start_date]=2026-05-01&filter[end_date]=2026-05-31&granularity=week.

Organization scoped

Read account-level totals with GET /api/v1/analytics/overview?filter[start_date]=2026-05-01&filter[end_date]=2026-05-31.

Sequence and lead detail

Use /analytics/sequence?filter[start_date]=2026-05-01&filter[end_date]=2026-05-31&granularity=week to compare stable subject revisions within each shared body, and lifetime /analytics/leads for lead detail.

Report read models

Commercial → Momentum

Momentum opens on the last 90 UTC days, including today, with weekly bars. Choose Since tracking began for full history, or select other dates. Funnel and Flow keep their existing defaults. Momentum uses the selected UTC dates. Positive replies, Bookings, Deals and Won show recorded counts alongside the preceding period of the same elapsed length. Comparisons before recorded history are unavailable, including Since tracking began. Stages count reached or further: conversations use their first Positive reply date; attributed deals without a Positive conversation enter only Deals and Won. The stages overlap, so their heights are not a combined total.

The chart uses days for up to 31 days, Monday-based weeks for up to 180 days, and months for longer selections. Select a segment to see the person, deal name where applicable, labelled cohort date and available thread link. Won values keep recurring and one-off amounts separate; missing values remain visible. A disconnected source says No CRM connected or No calendar connected instead of showing zero. Booking periods before recorded source coverage remain unmeasured, with an en dash in comparisons. Undated deals remain in full-history tiles and are explicitly excluded from dated bars.

The current incomplete bucket is marked Partial. Solid bars show recorded counts and a dashed extension projects the observed pace to the calendar period end after at least 10% has elapsed. Earlier buckets and selection-clipped buckets have no projection from clipping. The axis uses observed counts and dashed extensions stop at the top. Projections do not change tile counts and are not used to claim a completed-period trend.

Walk-ins shows Visits separately because they have no person attached. Grey brackets include uncertain navigation evidence when it adds visits. Shading marks time before tracking began and pauses when all eligible domains were unmeasured; an unknown tracking start is shown as unavailable coverage, never measured zero.

Commercial → Funnel

Funnel shows Positive, Conversation, Booking, Deal and Won. Each stage includes conversations that reached it or went further. Deal and Won count distinct attributed deals, or marks without a CRM. Multiple deals can make Deal larger than Booking. Lost and Not a fit retain Positive membership. Currently lost deals are not Won. Reopened deals retain their reached Won milestone, but their money belongs only to Open pipeline.

Keep Since tracking began for all history, or choose first Positive reply dates. By outreach month uses that same first-Positive cohort, including subsequent outcomes. Partial months are labelled; dates before booking tracking show an en dash. Select a chart bar for its monthly breakdown, or sort the table by any column. Calculation opens the basis for the figures. Leads emailed is not yet included.

Gross values use Average customer value; Value each (weighted) divides selected Won value plus weighted open value by the stage count, showing an en dash when incomplete. A disconnected CRM without recorded manual outcomes shows unknown Deal and Won; recorded marks remain visible with their source note. Won and Open pipeline show recorded amounts, with one-off values separate. Values: Monthly or Annual changes recurring amounts. Calculation explains weighted values, missing amounts, and the dated wins used for average sales cycle. The largest drop insight opens details and can be dismissed.

Use GET /api/v1/reports/commercial/summary or MCP workspace_report_commercial_summary_get. Optional start_date and end_date are paired inclusive UTC dates, up to 366 days. Omit both for full history. The report envelope contains data.funnel (counts, months, won_value, pipeline, became_customers, sales_cycle_days and sales_cycle_sample), connection availability and booking_history_start. Unknown values are null; unavailable sources are explicit. While attribution checks are pending, unchecked_deals gives their count; Deal, Won and Pipeline show an en dash and Still checking. Their counts and values remain null until assessment finishes.

Commercial → Deals

The compatibility field credited is true when the attribution check attributed this deal. pipeline.credited counts attributed open deals. In booking panel details, details.credited counts attributed scheduled bookings.

The attribution window for deals is 30 days after a campaign email or 90 days after a human reply or attributed meeting, measured to deal creation; other attribution checks still apply. With stored CRM deals available, Deal and Won show attributed deals. Each deal counts once; a conversation can show more than one deal. Assist chips identify deals outside attributed totals. Conversations with only lost attributed deals leave the lists and follow-up counts, with the excluded count stated. An open deal does not clear Reply needed.

Open deals and Pipeline use full history, with no date limit. Pipeline shows attributed open amounts and weighted amounts; assists stay separate. Values: Monthly or Annual converts recurring periods, while One-off stays labelled separately. Only known USD amounts enter totals. Amount missing, non-USD values, unknown periods and missing probabilities are stated rather than treated as known zero. Weighted value multiplies an amount by its probability. Expand Calculation for the basis.

A CRM deal marked won appears as Won even if its won date is missing. Missing dates show – and are excluded from date-based figures such as sales cycle. Deal links open the CRM and Last synced states freshness. All workspace members can read deal names and amounts. An attributed deal without a Positive conversation appears in Open deals and totals, without an invented conversation.

The Deal Slack Report includes Deal, Won and Pipeline when stored deals are available. Weekly Deal counts use creation dates; weekly Won counts require a recorded won date. Pipeline has no date limit. Without a CRM, set Average customer value in Settings → General for the Open deals estimate.

With no CRM connected, use Mark on a Positive conversation to choose Open, Won, Lost or Not a fit, or Clear. Open reaches Deal; Won reaches Won. Lost and Not a fit leave the lists and appear in the excluded count. Expand that count to clear an excluded mark. Marks do not change Positive membership or status. Connecting a CRM hides and ignores stored marks.

PUT /api/v1/reports/commercial/mark accepts case_id from the cases response and mark: open, won, lost, not_a_fit, or an empty string to clear. The MCP tool is workspace_commercial_mark_set. The saved response includes mark, the derived case or excluded_case, workspace-wide open_deals, monthly_value_cents and as_of, so a saved row and its totals can update immediately without waiting for full history. The same workspace access applies on all surfaces; a connected CRM returns a conflict. Status and stage filters apply to visible cases, excluded cases, Open deals and scheduled bookings. Scheduled bookings include Lost and Not a fit cases. The cases response includes excluded_count and excluded_cases (an empty array when none); has_more indicates another page in either visible or excluded cases. With a usable CRM and stored deals enabled, unfiltered open_deals counts workspace-wide attributed open deals, including deals without a case. Date, status, stage or case filters count only matching cases’ attributed open deals. Without a CRM, Open deals counts Open marks; an unset Average customer value displays an en dash.

Commercial is being introduced gradually. The Board groups Positive conversations by their furthest stage: Positive, Conversation or Booking. Select first Positive reply dates, or keep full history. Counts and current statuses cover that selection.

Reply needed means a lead reply within 30 UTC calendar days with no later qualifying touch. Active means you followed up after a reply within 7 days. Cooling means you followed up after a reply 8 to 30 days ago. Gone cold means the last lead reply was over 30 days ago. Hot is independent: the latest classified reply requests a meeting or proposal, brings in colleagues, or indicates readiness to proceed.

Calls logged in your connected CRM count as follow-up unless explicitly inbound and not connected. Calls with unset direction or outcome still count and read “Call logged”. Calls never placed (queued, canceled, failed, created, scheduled or pending) are excluded. Sent outbound SMS and manually logged Salesforce email Tasks also count as follow-up. Automatically generated email-thread copies and incoming native emails do not. A connected call reaches Conversation. A call after the latest reply clears Reply needed and starts a four-day wait. Calls appear in History. Meetings continue to count through bookings. Unknown call outcomes remain unknown.

Deals loads in stages. Its frame appears first, then recent conversations, with older conversations and full-history counts arriving afterwards. Bookings and Open deals load independently. A loading indicator means a result is not known yet; it is not zero. Changing between Board and Timeline retains the reads already made on that page. Marks refresh current data without closing cards.

The cases endpoint and workspace_report_commercial_cases_get accept scope=recent to return current cases that are not Gone cold, with the same status, stage, exclusions and global deal assignment as the full read. Omit scope for full history. Recent counts and paging cover only that subset; earliest_history_at is null until a full-history read. No result is cached.

For independent totals, scope=bookings returns upcoming_bookings, last_booking_at and last_booking_person; scope=deals returns open_deals, monthly_value_cents and pipeline. These scopes use full Positive history and shared exclusions, accept first-Positive date ranges, and return empty case lists with count zero rather than a conversation total. Scope cannot combine with case_id or History; totals scopes cannot combine with status or stage filters.

Upcoming bookings counts scheduled meetings in the next 14 days among the selected conversations. Engaged now counts conversations with a lead reply in the last 30 days. Cooling counts conversations in that status. Expand Gone cold to inspect companies, or open a card for follow-up details. State bars highlight matching cards. Links open Unibox; Commercial sends no messages.

Switch to Timeline for conversations grouped by the week of their latest reply, alongside bookings. Your browser remembers the view; Board remains the default. Recent covers replies in the last 30 UTC days; Gone cold is folded initially. History loads the recorded human touches and replies when opened. Bookings shows the next 28 days and the last 30 days by meeting date; Show older adds 30 days. Calendar days use UTC, and meeting times use your browser time zone. Missing calendar coverage is shown explicitly.

The cases endpoint and workspace_report_commercial_cases_get accept case_id and include_history=true together. History is omitted by default. With these two parameters the response contains top-level case_id and history, an empty cases list, and the workspace-wide earliest_history_at; it does not recompute case facts. History events expose at and kind (reply, touch or call; call events include a call object with at, provider, direction, outcome and nullable duration_seconds), with the same workspace scope and eligibility as the cases list.

The first cases page (offset=0, without History) includes calendar_connected (an eligible source exists), calendar_available (an eligible source has completed history sync), and crm_providers (an array of connected provider identifiers). Later pages and History omit these source fields.

Use GET /api/v1/reports/summary, /reports/deliverability, /reports/volume, and /reports/stocks for the same reporting data shown in the web UI. /reports/volume/all-time returns lifetime volume totals and monthly averages and takes no dates. A report request that runs out of time returns 504; try again later. Detailed deliverability views are under /reports/deliverability/{view}; only boxhost-trends accepts granularity. Speed to lead is at /reports/speed-to-lead; omit both dates for its seven-day default or supply both for a custom range. Check /reports/revenue/availability before requesting the conditional Revenue report at /reports/revenue.

Bookings

Close meetings use your existing enabled Close connection and the same Lead matching, attribution, Assist, own-team exclusion and follow-up rules. The booking date is the earlier of creation in Close and the meeting start, so a late import cannot earn attribution from an email sent after the meeting. Upcoming, in-progress and completed meetings are scheduled; canceled and declined meetings are canceled. Moving a meeting keeps its booking date. Unknown states and meetings without a start or end are not imported. A declined attendee is canceled. Your Close users are excluded. Copies in Close and other providers are not counted twice; shared calendar IDs also identify Close copies. A meeting removed from Close is retained as canceled with the reason “Meeting removed in Close.” Disconnecting removes Close coverage and retains recorded bookings. Meeting titles, attendee names, notes and transcripts are not stored.

Close history begins with your workspace's first retained campaign send, including imported outreach, and resumes over multiple checks when necessary. Checks run every 15 minutes, reading newly created meetings with a seven-day overlap and refreshing recorded meetings that are in the future or started in the last seven days. Meetings that started more than seven days ago are not routinely refreshed. If a meeting has not already been recorded, a person added more than seven days after its creation may not be discovered. These checks are not a complete historical update feed.

The speed-to-lead report returns AI replies metrics in data.ai_replies: Drafted, Sent as is, Sent edited, Discarded with reasons, No draft, No reply needed, Unsent, and median minutes from draft to send. The cohort uses draft creation time within period_start (inclusive) and period_end (exclusive), both UTC. Counts include their denominators and the timing sample size. This section is null when the workspace has no eligible AI replies history or the optional read is unavailable; the rest of the report remains available. See AI replies report definitions for each count.

Use GET /api/v1/bookings to list meetings Leads booked on the workspace's connected calendar, newest first. The source is Cal.com, Calendly, Google Calendar, Salesforce Events, Close meetings or, for a workspace with an enabled HubSpot CRM integration, HubSpot meetings, which include meetings synced from the team's calendars; provider says which (calcom, calendly, google_calendar, salesforce, close or hubspot). Cal.com reads bookings hosted by the connected user, beginning with bookings created on January 1, 2026. Accepted, pending and unconfirmed bookings are scheduled. Canceled bookings are recorded as canceled, including when first seen; a rejected booking becomes canceled only if it was already recorded. Cancellations and linked reschedules stay current. Disconnecting Cal.com removes its coverage but retains recorded bookings. Each booking names its Lead, campaign and, when one preceded the booking, its Positive conversation. An invitee first matches an emailed Lead's exact address. Otherwise, membership in the same company through any enabled HubSpot or Close CRM, or a usable Salesforce connection can link the booking to the emailed colleague with the latest Lightmeter touch within 30 days. With no CRM connected, the same corporate domain of the address actually emailed can establish membership; free-mail, personal, workspace sending and Beam user addresses do not qualify. Salesforce Account matching requires the same corporate email domain; free-mail and unrelated Account contacts cannot establish membership. An unavailable Salesforce connection does not block other providers. The actual invitee is retained, and match_method distinguishes invitee_email from company_colleague. Omit both dates for the last 90 UTC dates, or supply both for at most 400 days; filter[lead_id] and filter[conversation_id] narrow the list. When no eligible source has completed a sync, source and summary are null and an empty list does not mean no meetings. source.history_start bounds meeting creation date for HubSpot, Close, Cal.com, Google Calendar and Salesforce, and meeting start for Calendly; coverage uses the latest history start across eligible sources that have completed a sync. Coverage reports the least recently synced of those sources, and source.last_checked_at is when that source’s latest completed check began. summary counts the whole workspace for the dates; the Lead and conversation filters narrow only the list. limit caps the list at 1 to 500 bookings (default 500) and truncated says more exist. Status is scheduled, canceled, or rescheduled for a booking replaced by a new time, which keeps the original booking date. Each booking row exposes credited (true when the attribution check attributed this booking), assisted, credit_reason and credit_checked_at. All matched bookings remain in the list; Booked meetings and Booked Positive conversations count only attributed scheduled bookings. An Assist means the 30-day attribution window and seven-day quiet tests pass, but the first response was to your team. Its reason is “Your team converted them after a Lightmeter email.” The attributed and assisted flags are mutually exclusive. assisted_meetings counts assisted scheduled bookings separately. Salesforce booking attribution is assessed when activity evidence is available; unassessed_meetings counts scheduled Salesforce and Close bookings with no attribution assessment, excluded from Booked meetings and Assists. A follow-up to an earlier attributed or assisted meeting is neither attributed nor assisted. Canceled meetings counts cancellations regardless of attribution. The attribution window is 30 days after a Lightmeter email or human reply. Attribution also requires seven days without earlier contact with your team, and no response to your team before replying to Lightmeter. Contact evidence is combined from every enabled CRM: HubSpot contacts and associated company objects, and Close Lead members. Salesforce bookings additionally use readable Salesforce Contact/Lead and same-domain Account activity; unavailable or ambiguous evidence leaves a new booking unassessed. Close includes answered calls lasting at least 30 seconds, inbound SMS, inbound emails outside Lightmeter threads and meetings. Verified CRM-native human replies also count as touches. Unlogged channels remain invisible. No CRM passes the contact tests by default. Attribution is refreshed for unassessed bookings, bookings made in the last three days, and older bookings whose stored attribution coverage differs from the currently enabled CRM integrations. Existing bookings receive the Assist assessment once after rollout. Older bookings are also reassessed when an earlier attributed or assisted meeting changes their follow-up status; otherwise successful assessments do not cause recurring reads. The speed-to-lead report carries the same counts for its dates in data.bookings.

For the Timeline panel, date_field=starts_at filters meeting dates; the default remains booked_at. Summary always uses booking dates. offset and next_offset page through the list. Optional include_details=true adds attendee person, company and title, and workspace totals since the first retained booking. This display projection excludes deleted Leads. Totals distinguish scheduled Attributed and Assist bookings from all retained bookings. The same options are available through workspace_bookings_list.

Send timeline projection

Use GET /api/v1/campaigns/{campaign_id}/send-timeline to retrieve the campaign send projection shown in the campaign editor, including estimated completion instants in the campaign timezone when the underlying send evidence is precise. Estimates account for steady mailbox sending pace, trailing 24-hour limits, prior sends, effective lead timezones and follow-up waits. A late start has fewer planned sends that day. Urgent Auto Assign can use a wider pool of suitable mailboxes; completion estimates still reflect the configured sending hours and limits.

pending_leads_unsendable and pending_leads_awaiting_email_check count pending (not yet started) leads that can’t send and are excluded from the projection. Unsendable includes blocked email checks, missing addresses, and deleted leads; awaiting includes missing, pending, processing, or errored checks. Both fields are always present, including zero. Started leads are outside these counts.

Mailbox records in today_plan.mailboxes can include pacing_policy_version and pacing_ready_at. The readiness instant uses timezone_basis and describes cadence readiness; other sending prerequisites can still delay sending. at_pacing_limit means the mailbox is waiting for its next opportunity.

Base URL and Authentication

All requests use the standard bearer token header.

https://beam.lightmeter.io Authorization: Bearer your_api_key_here

Date-Scoped Example Request

GET
/api/v1/campaigns/{campaign_id}/analytics/timeseries?filter[start_date]=2026-05-01&filter[end_date]=2026-05-31&granularity=week
curl -X GET "https://beam.lightmeter.io/api/v1/campaigns/4ed5a7d2-320c-445e-a16c-7ab932bc259a/analytics/timeseries?filter[start_date]=2026-05-01&filter[end_date]=2026-05-31&granularity=week" \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json"

Reply Metric Semantics

The API exposes the combined End-autoreply response signal and its human-reply component.

  • reply_rate remains human-only.
  • end_autoreply_count and end_autoreply_rate combine human responders with automated non-bounce-only responders, counting each sender once.
  • Sender-level precedence applies internally: a later human reply moves the sender from the automated-only component into reply_rate without changing the combined End-autoreply total.
  • Both rates use the same deliverable-leads proxy denominator: leads_contacted - all_bounces.
  • Subject metrics are directional evidence for deciding what to enable, disable, or revise. Read rates together with their absolute counts and comparable sending conditions.

Workspace Report Example Request

GET
/api/v1/reports/deliverability?filter[start_date]=2026-05-01&filter[end_date]=2026-05-31
curl -X GET "/api/v1/reports/deliverability?filter[start_date]=2026-05-01&filter[end_date]=2026-05-31" \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json"

Campaign Click Evidence

Enable Click tracking in Settings → Tracking. Eligible public links in recipient-rendered campaign messages use short HTTPS URLs on the naked sending domain. Opted-in campaigns stop sending when tracking is unavailable. New-only setting changes affect campaigns created afterward; explicitly applying to existing campaigns changes their future click tracking, including old URLs. Authorized MIME and issued destinations remain stable. Existing campaigns can be deliberately re-enabled; disabled intervals cannot be recovered.

Lifetime, timeseries and sequence responses include click_tracking. Clicks counts distinct original leads with likely-human navigation on accepted tracked emails; its rate divides that count by distinct original leads who received those emails. Ten clicked leads among 100 tracked leads give 10% (10), regardless of repeat visits. The UI shows one primary number, without an optimistic bracket. The unique-leads link opens summary_filter=clicked using the same cohort. Forwarding retains original attribution.

Campaign visits have three classes: machine (automated/non_navigation, excluded), likely-human (human_candidate, counted), and ambiguous (unknown, retained but not counted). Inspect ambiguous visits with click_evidence=unknown. Automated link scanners and other bots are machine visits. A visit is likely-human only when Beam finds positive evidence of a person's browser opening the link from an ordinary ISP or business network, or through a recognized relay service such as Apple Private Relay, and no sign of automation. Visits through other VPN, proxy and hosting networks are not counted. Visits with missing or incomplete evidence remain ambiguous.

Visits before the email was accepted for delivery are excluded from reports. Classification is an estimate, never verified human identity.

The optimistic_* fields are deprecated compatibility aliases equal to the corresponding primary fields, including null rates. Unknown visits never add clicked leads. When unknown visits exist without a qualifying click, click_rate and its alias remain null; with a tracked-send denominator, the UI shows a primary count of zero. A historical-gap indicator records when tracking was off; missed visits are absent. Earlier untracked emails stay outside the denominator. Classification updates do not automatically reclassify older visits.

Whole-period unique totals are computed directly and cannot be summed from date buckets or variants. Buckets use visit time and the tracked-send cohort accepted before the bucket ends. Sequence subject rows sharing a step and variant expose that same variant cohort; those rows are not additive. click_rate=null means no usable click result, including an absent tracked-send denominator or unknown-only observations. Versions are sorted unique values from included observations. A pause remains incomplete historical coverage after resumption. Existing positive-reply-share and other metrics retain their units.

Lead drilldown accepts click_evidence=tracked|estimated|automated|unknown|non_navigation. Reports exclude deleted/archived campaigns, deleted leads, removed membership and attribution tombstones; moved leads retain their original send cohort. Short URLs publicly expose their saved destination. Interactive replies, test sends, attachments, protected links and ambiguous prose keep original URLs.

Sequence email analytics return is_step_paused for the whole step, separately from subject or variant is_paused eligibility. Paused copy and historical results remain visible. Use Pause or Resume beside a step in Step Performance, in the table or responsive cards, just as in Ready. At least one step with an enabled variant must remain active. The result names the next step, or explains that waiting leads stay Started until a later step is available. The sequence analytics MCP tool returns the same fields.