> ## Documentation Index
> Fetch the complete documentation index at: https://heybtw.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# get_event_attribution

> Sourced/influenced pipeline attribution per event, with an optional program-level cost-per-meeting rollup.

<Note>
  This page documents the **Python MCP surface** (`mcp.heybtw.com`). It reflects `mcp-server/tools/event_attribution.py` as of this page's publication — see [Schema stability](/docs/integrations/mcp-tools#schema-stability).
</Note>

## Purpose

`get_event_attribution` returns one row per event with signup/MQL/opportunity/meeting counts and, when HubSpot is connected, pipeline revenue broken down as [Sourced vs. Influenced](/docs/concepts/attribution-model) per company and per partner. All revenue figures come from heyBTW's canonical attribution resolver — the same numbers the in-app Funnel and Attribution dashboards show, never re-derived independently.

## When to use this

* "Which deals can we attribute to the Berlin Fintech Dinner in March?"
* Comparing event ROI across a date range, especially alongside `program_summary.cost_per_meeting` for paid events.
* Read [Representing attribution honestly](/docs/integrations/mcp-tools#representing-attribution-honestly) before an agent reports these numbers to an end user — Sourced is a stronger claim than Influenced and should not be over-asserted.

## Parameters

| Name         | Type                   | Required | Default | Description                                       | Example        |
| ------------ | ---------------------- | -------- | ------- | ------------------------------------------------- | -------------- |
| `channel_id` | string                 | No       | `null`  | Restrict to a single event. Omit for all events.  | `"chn_88af1"`  |
| `date_from`  | string (ISO 8601 date) | No       | `null`  | Only include events starting on/after this date.  | `"2026-01-01"` |
| `date_to`    | string (ISO 8601 date) | No       | `null`  | Only include events starting on/before this date. | `"2026-06-30"` |

## Default behavior

Called with no parameters, returns **every** event in the workspace, sorted newest-first, with no result cap. When HubSpot is not connected, every row still returns (signup/MQL/meeting counts are always available) but omits `pipeline`, `attribution_breakdown`, and `partner_attribution` entirely — check `crm_enriched` per row before expecting those keys.

## Sample request

```json theme={null}
{
  "tool": "get_event_attribution",
  "arguments": { "date_from": "2026-01-01" }
}
```

## Sample response

```json theme={null}
{
  "tool": "get_event_attribution",
  "query_time_ms": 118.6,
  "result_count": 1,
  "data": [
    {
      "event_name": "Robotics Summit SF 2026",
      "channel_id": "chn_88af1",
      "event_date": "2026-06-18T00:00:00+00:00",
      "total_signups": 210,
      "mql_count": 34,
      "opportunity_count": 9,
      "meeting_booked_count": 14,
      "partner_sourced_count": 68,
      "conversion_rate": 0.1619,
      "partner_sourced_pct": 0.3238,
      "crm_enriched": true,
      "pipeline": {
        "sourced_revenue": 128400.0,
        "won_revenue": 42000.0,
        "company_count": 19
      },
      "attribution_breakdown": [
        {
          "company": "Lighthouse Robotics",
          "domain": "lighthouserobotics.example",
          "revenue": 38000.0,
          "is_won": false,
          "attribution_type": "sourced"
        },
        {
          "company": "Vantage Fields Inc",
          "domain": "vantagefields.example",
          "revenue": 12500.0,
          "is_won": true,
          "attribution_type": "influenced"
        }
      ],
      "partner_attribution": [
        {
          "partner": "direct",
          "sourced_revenue": 128400.0,
          "won_revenue": 42000.0,
          "company_count": 19
        }
      ]
    }
  ],
  "metadata": {
    "data_sources_queried": ["Channel", "EventSignUp", "EventAttributionOpportunity"],
    "date_range_applied": "2026-01-01 to now",
    "filters_applied": { "channel_id": null, "date_from": "2026-01-01", "date_to": null, "crm_enriched": true },
    "coverage_note": null
  },
  "program_summary": {
    "cost_per_meeting": {
      "total_invested_usd": 24000.0,
      "paid_event_count": 3,
      "meetings_from_paid_events": 31,
      "cost_per_meeting_usd": 774.19
    }
  }
}
```

## Response field reference

### Envelope

| Field                         | Type                  | Description                                                                                                                                                                                                  |
| ----------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `tool`                        | string                | Always `"get_event_attribution"`.                                                                                                                                                                            |
| `result_count`                | integer               | Number of events returned.                                                                                                                                                                                   |
| `data`                        | array                 | One object per event.                                                                                                                                                                                        |
| `program_summary`             | object \| **omitted** | Present only when at least one paid event with cost data exists in the filtered range. **This is the one place `program_summary` appears across all 8 tools** — check for key presence, don't assume `null`. |
| `metadata.date_range_applied` | string \| null        | Human-readable range, e.g. `"2026-01-01 to now"`, or `null` if neither `date_from` nor `date_to` was given.                                                                                                  |
| `metadata.coverage_note`      | string \| null        | `"Connect HubSpot CRM to unlock pipeline values"` when CRM is not connected.                                                                                                                                 |

### `data[i]`

| Field                                                                                                  | Type                               | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| ------------------------------------------------------------------------------------------------------ | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `event_name` / `channel_id` / `event_date`                                                             | string                             | Event identity.                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| `total_signups` / `mql_count` / `opportunity_count` / `meeting_booked_count` / `partner_sourced_count` | integer                            | Funnel counts for the event.                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `conversion_rate`                                                                                      | number (0–1)                       | `mql_count / total_signups`, `0.0` if no signups.                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `partner_sourced_pct`                                                                                  | number (0–1)                       | `partner_sourced_count / total_signups`.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `crm_enriched`                                                                                         | boolean                            | `true` only when CRM is connected **and** the attribution resolver successfully returned data for this call — a resolver timeout degrades every row's `crm_enriched` to `false`, indistinguishable from "CRM not connected" in the row itself (the top-level `metadata.coverage_note` is your only signal to tell the two apart, and only fires for the "not connected" case — a resolver-timeout degrade is currently silent at the row level).                                         |
| `pipeline`                                                                                             | object, present iff `crm_enriched` | `{ sourced_revenue, won_revenue, company_count }`. `sourced_revenue` here is `sourcedPipeline + influencedPipeline` combined (a naming legacy — despite the field name, it is NOT sourced-only; use `attribution_breakdown[].attribution_type` for the actual sourced/influenced split per company).                                                                                                                                                                                     |
| `attribution_breakdown`                                                                                | array, present iff `crm_enriched`  | One entry per company with attributed revenue at this event: `{ company, domain, revenue, is_won, attribution_type }`. `attribution_type` ∈ `"sourced"` \| `"influenced"` \| `null`. `domain` may be `null` when unresolved. Deduplicated by company.                                                                                                                                                                                                                                    |
| `partner_attribution`                                                                                  | array, present iff `crm_enriched`  | Revenue grouped by partner: `{ partner, sourced_revenue, won_revenue, company_count }`. **Current limitation:** the canonical attribution resolver does not expose which partner sourced each deal, so every row's revenue is bucketed under a single `partner: "direct"` entry today — this array does not yet reflect real per-partner pipeline splits. Use [`get_partner_insights`](/docs/mcp-tools/get-partner-insights)`.pipeline_impact` for a partner-accurate revenue figure instead. |

### `program_summary.cost_per_meeting` (top-level, sibling of `data`)

| Field                       | Type           | Description                                                                                                                                                                    |
| --------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `total_invested_usd`        | number \| null | Total event cost across paid events in the filtered range.                                                                                                                     |
| `paid_event_count`          | integer        | Number of events with cost data.                                                                                                                                               |
| `meetings_from_paid_events` | integer        | Meetings booked at those paid events.                                                                                                                                          |
| `cost_per_meeting_usd`      | number \| null | `total_invested_usd / meetings_from_paid_events`. `null` means "not applicable," never `$0` or `Infinity` — sourced verbatim from the canonical resolver, not recomputed here. |

## Errors

Same generic-sanitized-error behavior as every tool on this surface — see [`get_workspace_overview` — Errors](/docs/mcp-tools/get-workspace-overview#errors). An unmatched `channel_id` returns `result_count: 0`, not an error.

## Pagination and limits

No caller-facing `limit` parameter and no cursor pagination — every matching event is returned. Internally the row fetch is capped at 500 events (a fixed server-side safety limit), well beyond any workspace's event count today.

## Related tools

* [`get_event_summary`](/docs/mcp-tools/get-event-summary) — single-event deep dive (attendance, seniority, partner performance) with the same `pipeline` shape for one `channel_id`.
* [`get_partner_insights`](/docs/mcp-tools/get-partner-insights) — the accurate per-partner revenue figure that `partner_attribution` cannot yet provide.
* [`get_workspace_overview`](/docs/mcp-tools/get-workspace-overview) — `program_metrics.attribution_summary` is a workspace-wide, all-time rollup from the same resolver.
