# Count engaged leads by CRM pond, stage, agent or tag

Source: https://help.ruuster.com/api/leads-crm-segments

```http
GET https://api.ruuster.com/v1/leads/crm-segments
```

How many of your leads engaged on your Ruuster sites in a period, counted by where they sit in your CRM (pond, stage, assigned agent or tag), optionally filtered to some ponds or stages and with the leads listed. Answers "how many leads in our inactive ponds engaged meaningfully?" in one call.

- Authentication: `x-api-key` and `x-email` headers of an owner or admin
- Rate limit: *lookup* call, 20 per minute per key, within the 120 per minute
- Your CRM: `x-crm-vendor` and `x-crm-key` headers with your CRM's API key, used for this request only. See [Connect your CRM](https://help.ruuster.com/api/crm)
- Rows count against the daily lead-row quota (50,000 by default)

Ruuster activity counted by your CRM's own segments. Ruuster takes every lead engaged at the `engagement` level in the range, looks each one up in your CRM by the CRM id Ruuster's CRM sync stored on the lead (`crmExternalId`), and counts them by `groupBy`. Filter to some ponds, stages, tags or one agent, and add `list=1` for the leads themselves.

Typical questions: "how many leads in our inactive ponds have engaged meaningfully with Ruuster this month?" (`groupBy=pond&pond=inactive`), "which stages are our most engaged leads in?" (`groupBy=stage&engagement=strong`), "which agents' leads are most active?" (`groupBy=agent`).

This call reads your CRM live with your CRM's API key (headers `x-crm-vendor` and `x-crm-key`; used for this request only, never stored), with that key's own permissions. Follow Up Boss supports every grouping. Sierra and Sure Send can't look many people up at once, so for them `groupBy=stage` and `groupBy=tag` count from the copy of each lead's CRM stage and tags that Ruuster's CRM sync keeps (no CRM call), and ponds and agents answer `400 crm_not_supported`. See [Connect your CRM](https://help.ruuster.com/api/crm).

## Query parameters

| Name | Type | Default | Description |
|---|---|---|---|
| `from` | date | 30 days before `to` | First day of Ruuster activity, `YYYY-MM-DD` in America/Chicago, included. At most 93 days |
| `to` | date | tomorrow | Day after the last day, `YYYY-MM-DD`, excluded. The default includes today |
| `engagement` | `any` \| `viewed` \| `meaningful` \| `strong` | `meaningful` | Who counts as engaged on Ruuster: `meaningful` 3 or more listing views, or any favorite, tour request, contact-agent click or share; `strong` a tour request or contact-agent click, 10 or more views, or 2 or more favorites; `viewed` viewed at least one listing; `any` any recorded activity |
| `groupBy` | `pond` \| `stage` \| `agent` \| `tag` | `pond` | What to count by. A lead counts once per tag it carries |
| `pond` | string | | Only people in these ponds: a pond id, or a name to match (comma-separate several), e.g. `inactive` matches every pond whose name contains it |
| `stage` | string | | Only people in this CRM stage (comma-separate several) |
| `tag` | string | | Only people carrying this CRM tag (comma-separate several; any of them) |
| `assignedUserId` | string | | Only people assigned to this CRM user (an id from [Get your CRM's vocabulary](https://help.ruuster.com/api/crm-overview)) |
| `list` | `0` \| `1` | `0` | `1` also returns the matching leads, most engaged first |
| `limit` | integer | `50` | With `list=1`, most leads returned, 1 to 500 |

## Response

| Field | Description |
|---|---|
| `segments[]` | One row per pond, stage, agent or tag, largest first: `key`, `name`, `leads`, and how many of them were `strong`, `meaningful` and `viewed`, their `propertyViews` and the latest `lastActivityAt`. People in no pond, with no stage or tag, or unassigned have their own row (`key` `none`) |
| `totals` | `engagedOnRuuster`, `linkedToCrm`, `checkedInCrm`, `foundInCrm`, `notFoundInCrm`, `matchingFilters` (the leads counted) |
| `criteria` | The rules in words, and with `pond` the ponds it matched |
| `ponds` | Every pond in the account (with `groupBy=pond` or a `pond` filter) |
| `leads` | With `list=1`: rows like [Find engaged leads your CRM hasn't called](https://help.ruuster.com/api/leads-follow-up) |

`meta.crm` names the CRM and its source (live, or Ruuster's synced copy), the number of CRM calls made, and any caution. Up to the 2,000 most engaged leads linked to your CRM are looked up per call.

## Example request

cURL:

```bash
curl -s "https://api.ruuster.com/v1/leads/crm-segments?engagement=meaningful&groupBy=pond&pond=inactive" \
  -H "x-api-key: $RUUSTER_API_KEY" \
  -H "x-email: $RUUSTER_EMAIL" \
  -H "x-crm-vendor: fub" \
  -H "x-crm-key: $CRM_API_KEY"
```

Node.js:

```javascript
const res = await fetch("https://api.ruuster.com/v1/leads/crm-segments?engagement=meaningful&groupBy=pond&pond=inactive", {
  headers: {
    "x-api-key": process.env.RUUSTER_API_KEY,
    "x-email": process.env.RUUSTER_EMAIL,
    "x-crm-vendor": "fub",
    "x-crm-key": process.env.CRM_API_KEY,
  },
});
const body = await res.json();
if (!body.ok) throw new Error(`${body.error.code}: ${body.error.message} (${body.requestId})`);
console.log(body.data);
```

Python:

```python
import os
import requests

res = requests.get(
    "https://api.ruuster.com/v1/leads/crm-segments?engagement=meaningful&groupBy=pond&pond=inactive",
    headers={"x-api-key": os.environ["RUUSTER_API_KEY"], "x-email": os.environ["RUUSTER_EMAIL"], "x-crm-vendor": "fub", "x-crm-key": os.environ["CRM_API_KEY"]},
    timeout=30,
)
body = res.json()
if not body["ok"]:
    raise RuntimeError(f'{body["error"]["code"]}: {body["error"]["message"]} ({body.get("requestId")})')
print(body["data"])
```

## Example response

```json
{
  "ok": true,
  "data": {
    "segments": [
      { "key": "4", "name": "Inactive Buyers", "leads": 57, "strong": 9, "meaningful": 57, "viewed": 55, "propertyViews": 1183, "lastActivityAt": "2026-10-21T22:40:12Z" },
      { "key": "9", "name": "Inactive - Sellers", "leads": 11, "strong": 1, "meaningful": 11, "viewed": 10, "propertyViews": 142, "lastActivityAt": "2026-10-20T15:02:33Z" }
    ],
    "totals": { "engagedOnRuuster": 406, "linkedToCrm": 351, "checkedInCrm": 351, "foundInCrm": 333, "notFoundInCrm": 18, "matchingFilters": 68 },
    "criteria": {
      "engagement": "meaningful",
      "engagementRule": "3 or more listing views, or any favorite, tour request, contact-agent click or share",
      "groupBy": "pond",
      "pond": "inactive",
      "ponds": [ { "id": "4", "name": "Inactive Buyers" }, { "id": "9", "name": "Inactive - Sellers" } ]
    },
    "ponds": [ { "id": "2", "name": "New Leads" }, { "id": "4", "name": "Inactive Buyers" }, { "id": "9", "name": "Inactive - Sellers" } ]
  },
  "meta": {
    "range": { "from": "2026-09-22", "to": "2026-10-22", "tz": "America/Chicago" },
    "coverage": { "from": "2026-07-03", "to": "2026-10-22", "stableBefore": "2026-10-20" },
    "crm": { "vendor": "fub", "label": "Follow Up Boss", "source": "Follow Up Boss, live, with your API key", "calls": 5, "note": "A lead counts once per pond." }
  }
}
```
