# Get new-lead stats

Source: https://help.ruuster.com/api/leads-stats

```http
GET https://api.ruuster.com/v1/leads/stats
```

New leads per day, week or month, optionally broken down by first-visit source and medium.

- Authentication: `x-api-key` and `x-email` headers of an owner or admin
- Rate limit: 120 requests per minute per key

## Query parameters

| Name | Type | Default | Description |
|---|---|---|---|
| `from` | date | 30 days before `to` | First day, `YYYY-MM-DD` in America/Chicago, included |
| `to` | date | today | Day after the last day, `YYYY-MM-DD`, excluded |
| `granularity` | string | `week` | `day`, `week` (Monday start) or `month` |
| `groupBy` | string | | `source` adds `bySource[]` to each bucket |

## Response

Each bucket in `data.series` has `created`, `registered` (created a Ruuster account) and `unregistered` (synced from your CRM). With `groupBy=source`, `bySource[]` has `source`, `medium`, `created` and `engagedWithin7d` (leads with at least one action in the 7 days after creation; it can still rise for the latest week).

`(crm)` as a source means a contact synced from your CRM that hasn't visited yet. A lead's source is its first tagged visit, so sources only line up with [Get website traffic](https://help.ruuster.com/api/traffic) where your links carry UTM tags.

## Example request

cURL:

```bash
curl -s "https://api.ruuster.com/v1/leads/stats?from=2026-09-14&to=2026-09-28&granularity=week&groupBy=source" \
  -H "x-api-key: $RUUSTER_API_KEY" \
  -H "x-email: $RUUSTER_EMAIL"
```

Node.js:

```javascript
const res = await fetch("https://api.ruuster.com/v1/leads/stats?from=2026-09-14&to=2026-09-28&granularity=week&groupBy=source", {
  headers: {
    "x-api-key": process.env.RUUSTER_API_KEY,
    "x-email": process.env.RUUSTER_EMAIL,
  },
});
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/stats?from=2026-09-14&to=2026-09-28&granularity=week&groupBy=source",
    headers={"x-api-key": os.environ["RUUSTER_API_KEY"], "x-email": os.environ["RUUSTER_EMAIL"]},
    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": {
    "series": [
      { "bucket": "2026-09-14", "created": 148, "registered": 61, "unregistered": 87,
        "bySource": [
          { "source": "facebook", "medium": "paid_social", "created": 52, "engagedWithin7d": 19 },
          { "source": "google", "medium": "cpc", "created": 23, "engagedWithin7d": 11 },
          { "source": "(crm)", "medium": "(none)", "created": 64, "engagedWithin7d": 9 },
          { "source": "(direct)", "medium": "(none)", "created": 9, "engagedWithin7d": 4 }
        ] },
      { "bucket": "2026-09-21", "created": 163, "registered": 70, "unregistered": 93,
        "bySource": [
          { "source": "facebook", "medium": "paid_social", "created": 58, "engagedWithin7d": 21 },
          { "source": "google", "medium": "cpc", "created": 27, "engagedWithin7d": 13 },
          { "source": "(crm)", "medium": "(none)", "created": 69, "engagedWithin7d": 8 },
          { "source": "(direct)", "medium": "(none)", "created": 9, "engagedWithin7d": 3 }
        ] }
    ],
    "totals": { "created": 311, "registered": 131, "unregistered": 180 }
  },
  "meta": { "range": { "from": "2026-09-14", "to": "2026-09-28", "tz": "America/Chicago" }, "granularity": "week" }
}
```
