# Usage

URL: https://email-validation.org/docs/api/usage/
Updated: 2026-10-20

> Documentation index: https://email-validation.org/llms.txt

`GET /v1/usage` returns how many credits you used, per day or per API key, for any window within the last
90 days. It is free and needs a key with the `account:read` scope.

## Request

| Parameter | Description |
|---|---|
| `from` | First day, `YYYY-MM-DD` in UTC, no earlier than 90 days back (today included). Defaults to the start of the 90-day range that ends on `to`. |
| `to` | Last day, `YYYY-MM-DD` in UTC, within the same window. Defaults to today. |
| `group_by` | `day` (default) or `key`. |

**curl**

```bash
curl "https://api.email-validation.org/v1/usage?from=2026-11-01&to=2026-11-30&group_by=day" \
  -H "Authorization: Bearer $EV_API_KEY"
```

**JavaScript**

```js
const params = new URLSearchParams({ from: '2026-11-01', to: '2026-11-30', group_by: 'key' });
const res = await fetch(`https://api.email-validation.org/v1/usage?${params}`, {
  headers: { Authorization: `Bearer ${process.env.EV_API_KEY}` },
});
const usage = await res.json();
for (const item of usage.items) console.log(item.key_id, item.credits_used);
```

**Python**

```python
import os

import requests

resp = requests.get(
    "https://api.email-validation.org/v1/usage",
    params={"from": "2026-11-01", "to": "2026-11-30", "group_by": "day"},
    headers={"Authorization": f"Bearer {os.environ['EV_API_KEY']}"},
    timeout=10,
)
resp.raise_for_status()
for day in resp.json()["items"]:
    print(day["date"], day["credits_used"])
```

## Response

```json
{
  "from": "2026-11-01",
  "to": "2026-11-02",
  "group_by": "day",
  "totals": {
    "credits_used": 1212,
    "by_status": {
      "deliverable": 1014,
      "undeliverable": 121,
      "risky": 77,
      "unknown": 31
    }
  },
  "items": [
    {
      "date": "2026-11-01",
      "credits_used": 640,
      "by_status": {
        "deliverable": 538,
        "undeliverable": 61,
        "risky": 41,
        "unknown": 17
      }
    },
    {
      "date": "2026-11-02",
      "credits_used": 572,
      "by_status": {
        "deliverable": 476,
        "undeliverable": 60,
        "risky": 36,
        "unknown": 14
      }
    }
  ]
}
```

With `group_by=key`, each item has a `key_id`, the key's `name` and `last4` instead of a `date`, and no status split.
Key ids identify keys in the dashboard; the API never returns the keys themselves. Items count only credits spent
through an API key: bulk jobs and dashboard checks are not tied to a key, so `totals` (always the whole account, the
same as with `group_by=day`) can be larger than the sum of the items.

## Exact and approximate numbers

- **Credit totals** (`credits_used` per day or per key, and `totals.credits_used`) come from the credit ledger and
  are exact. They include API, MCP, dashboard and bulk usage.
- **The split by status** (`by_status`) is compiled from request records of API, MCP, dashboard and bulk checks. It
  is approximate and can lag behind by up to an hour.

Use the daily totals for reconciliation and the splits for trends.

## Errors

A `from` or `to` more than 90 days back (usage covers the last 90 days, today
included), a `from` after `to`, or a malformed date returns `400 invalid_request`; the message names the earliest
day you can ask for. Other errors are listed on [Errors](https://email-validation.org/docs/errors/).
