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

# Metrics

> Meetings booked, sit rate, dial activity and pipeline value — and exactly how each is counted.

The `/v1/metrics/*` endpoints return the aggregates behind a sales dashboard. Every number is computed the same way the Cockpit computes it, so a figure from the API and the same figure on screen will agree.

Start with [`GET /v1/metrics/summary`](/api-reference/metrics/workspace-summary) — one request covering meetings booked, sit rate, dial activity, pipeline created, deals won and lost, and new leads.

```bash theme={"dark"}
curl "https://backend.leadey.ai/v1/metrics/summary?from=2026-07-01T00:00:00Z&to=2026-07-31T23:59:59Z&timezone=Europe/London" \
  -H "Authorization: Bearer sk_live_your_key_here"
```

## Sit rate

Sit rate is the share of held meetings someone actually turned up to:

```
sitRate = attended / (attended + noShow)
```

The subtlety is the denominator. Attendance is a **manual mark** a rep puts on a past meeting — attended or no-show — and plenty of meetings never get marked at all. Those are excluded from the calculation entirely, because counting an unmarked meeting as a no-show would report a sit rate far below reality.

That means the rate is only as good as your team's marking habits, so every response tells you how much of the period has been marked up:

| Field             | Meaning                                        |
| ----------------- | ---------------------------------------------- |
| `booked`          | Every meeting in the window                    |
| `past`            | Already started                                |
| `upcoming`        | Still to come                                  |
| `attended`        | Marked as attended                             |
| `noShow`          | Marked as a no-show                            |
| `dispositioned`   | `attended + noShow` — the sit-rate denominator |
| `undispositioned` | Past meetings nobody has marked                |

Check `undispositioned` before you trust `sitRate`. A rate of `0.5` off two marked meetings out of fifty held is not a sit rate — it's a sample of two.

<Note>
  Rates are `null`, never `0`, when the denominator is empty. A window with no marked meetings returns `sitRate: null`, so you can tell "no data" from "nobody showed up".
</Note>

## What counts as a booked meeting

Meetings reach Leadey from three places, and the same meeting often arrives from more than one:

* A **Calendly** booking
* A meeting **booked in Leadey**, through the scheduler on a lead
* An event on a rep's **connected Google or Outlook calendar**

The API merges all three, removes duplicates, and counts what's left. So a meeting booked in Leadey that then syncs back from Google is one meeting, not two.

Only meetings **linked to a lead** are counted. A rep's lunch or an internal stand-up never appears — every meeting the API returns can be traced to a lead, which is also why each carries a `leadId`.

Because a meeting's identity spans sources, its `id` is a composite `source:id` — for example `leadey:sm_123`. Use that whole string with [`GET /v1/meetings/{key}`](/api-reference/meetings/get-a-meeting).

## Timezones

Any metric bucketed by day needs to know which day you mean. There's no workspace-wide timezone, so pass one:

```
?groupBy=day&timezone=Europe/London
```

`timezone` takes an [IANA name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) and **defaults to `UTC`**. It matters more than it looks: a 9pm meeting in London falls on the next UTC day, so a daily report built without it will file some meetings against the wrong date. Every response echoes the timezone it used in `window.timezone`.

## Money and currencies

Values are **decimal strings**, not numbers:

```json theme={"dark"}
{ "currency": "GBP", "count": 3, "value": "15000.50", "weightedValue": "8500.45" }
```

A string, because JSON numbers are floats and money that round-trips through a float doesn't always come back the same.

Totals are always reported **per currency**, as an array. If your pipeline holds GBP and USD deals, you get one entry each — the API will never add them together, because a number that mixes currencies without a conversion rate means nothing. Single-currency workspaces get a one-entry array.

## Grouping

`groupBy` splits the totals into buckets while keeping the overall figures:

| Value      | Buckets by                                         |
| ---------- | -------------------------------------------------- |
| `day`      | Calendar day in your `timezone`                    |
| `week`     | ISO week, e.g. `2026-W31`                          |
| `rep`      | The user who booked the meeting or placed the call |
| `campaign` | Campaign id                                        |

Each bucket carries the same fields as `totals`, plus the `key` it's grouped on. Resolve a `rep` key with [`GET /v1/users`](/api-reference/reference/list-users).

## Windows

All metrics endpoints take `from` and `to` as ISO 8601 timestamps. Omit them and you get the last 30 days. A window longer than **62 days** is clamped — pull long ranges as consecutive requests rather than one large one.
