# Usage and spend

Read what your workspace has used and spent this period, break it down by day, product, profile or account, and track calls and SMS volumes.

The usage endpoints answer "what have we used, and what will it cost?" from code. They power the [Usage](https://pozy.ai/dashboard/usage) page in the dashboard, and they are how platforms built on Pozy work out what each customer costs them. All amounts are in US dollars unless a field name ends in `Cents`.

## Snapshot of the current period

`GET /v1/usage` with no parameters returns a snapshot: connected accounts, profiles, X call counts and spend so far.

```bash cURL
curl https://api.pozy.ai/v1/usage \
  -H "Authorization: Bearer $POZY_API_KEY"
```
```ts Node
const res = await fetch("https://api.pozy.ai/v1/usage", {
  headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
console.log(data.usage.connectedAccounts, data.spend.currentPeriodCents);
```
```python Python
import os, requests

resp = requests.get(
    "https://api.pozy.ai/v1/usage",
    headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
)
print(resp.json()["spend"])
```

```json
{
  "planName": "Usage-based",
  "billingPeriod": "monthly",
  "billingAnchorDay": 1,
  "hasAccess": true,
  "usage": {
    "profiles": 14,
    "connectedAccounts": 31,
    "lastReset": "2026-10-01T00:00:00.000Z",
    "xApiCallsByOperation": { "posts_read": 120, "content_create": 18, "content_create_with_url": 4, "dm_read": 0, "dm_send": 0 }
  },
  "spend": { "currentPeriodCents": 9370, "creditsRemainingCents": 0, "xSpendCents": 160, "xSpendLimitCents": 5000 }
}
```

For the plan, the billing period, caps and payment status in one call, use [`GET /v1/billing`](https://pozy.ai/docs/billing/billing#when-you-are-charged).

## Spend over a range

Add any of the range parameters and the same endpoint returns metered spend instead, day by day and per product:

```bash Terminal
curl "https://api.pozy.ai/v1/usage?range=30d&granularity=day" \
  -H "Authorization: Bearer $POZY_API_KEY"
```

| Parameter | Values | Notes |
| --- | --- | --- |
| `range` | `cycle` (default), `prev-cycle`, `7d`, `14d`, `30d`, `3mo`, `12mo`, `custom` | `cycle` is the current calendar month. |
| `from`, `to` | `YYYY-MM-DD` | Required with `range=custom`. |
| `granularity` | `day` (default), `month`, `total` | `total` returns totals only, no series. |
| `groupBy` | `profile`, `account` | Adds an `attribution` breakdown. |
| `profileId` | profile id | Only that profile's share. |
| `accountId` | account id | Only that account's share. |

The response:

| Field | What it holds |
| --- | --- |
| `days` | One row per day (or month) with the dollar amount for each product. |
| `totals` | The range's total per product, plus `total`. |
| `lineItems` | The lines as they would appear on an invoice, with `name`, `product`, `quantity` and `totalUsd`. |
| `subtotals` | `recurringUsd` (accounts, numbers) and `usageUsd` (everything metered). |
| `peaks` | The highest number of connected accounts and phone numbers in the range. |
| `period` | The range actually used, and whether it is a billing `cycle` or a rolling `window`. |

Products are `accounts`, `numbers`, `imessage`, `calls`, `sms`, `messages`, `verify`, `dlc`, `xApi`, `ads`, `credits` (the free tier credit, negative) and `other`.

## What each customer costs

With `groupBy=profile` the response adds `attribution`: one entry per profile with its share of each product, plus whatever belongs to no single profile.

```bash cURL
curl "https://api.pozy.ai/v1/usage?range=cycle&granularity=total&groupBy=profile" \
  -H "Authorization: Bearer $POZY_API_KEY"
```
```ts Node
const res = await fetch("https://api.pozy.ai/v1/usage?range=cycle&granularity=total&groupBy=profile", {
  headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
for (const g of data.attribution.groups) console.log(g.key, g.totalUsd);
console.log("not attributed:", data.attribution.unattributed.totalUsd);
```
```python Python
resp = requests.get(
    "https://api.pozy.ai/v1/usage",
    headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
    params={"range": "cycle", "granularity": "total", "groupBy": "profile"},
).json()
for g in resp["attribution"]["groups"]:
    print(g["key"], g["totalUsd"])
```

```json
{
  "groupBy": "profile",
  "groups": [
    { "key": "6720f3b1c9e4a85d2f0b7c14", "byProduct": { "accounts": 14.4, "sms": 2.31 }, "totalUsd": 16.71 },
    { "key": "6722b8e05d1f4a97c3e2b018", "byProduct": { "accounts": 9.6 }, "totalUsd": 9.6 }
  ],
  "unattributed": { "byProduct": { "credits": -12, "dlc": 9 }, "totalUsd": -3 },
  "totals": { "totalUsd": 23.31 }
}
```

The groups plus `unattributed` always add up to `totals`. Workspace-wide items such as the free tier credit and 10DLC registration fees land in `unattributed`. Account costs are shared out by each profile's share of the account-days, so a customer who connected accounts mid-month carries only their part.

A profile-scoped key can read its own profile's usage with `profileId`. Without it, the call needs a full-access key.

## Calls and SMS volumes

Two endpoints report telephony volumes with their own filters:

```bash cURL
curl "https://api.pozy.ai/v1/usage/calls?since=2026-10-01&until=2026-10-31&groupBy=number" \
  -H "Authorization: Bearer $POZY_API_KEY"

curl "https://api.pozy.ai/v1/usage/sms?since=2026-10-01&until=2026-10-31&groupBy=day" \
  -H "Authorization: Bearer $POZY_API_KEY"
```
```ts Node
const callsRes = await fetch("https://api.pozy.ai/v1/usage/calls?since=2026-10-01&until=2026-10-31&groupBy=number", {
  headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const calls = await callsRes.json();
if (!callsRes.ok) throw new Error(calls.error);
const smsRes = await fetch("https://api.pozy.ai/v1/usage/sms?since=2026-10-01&until=2026-10-31&groupBy=day", {
  headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const sms = await smsRes.json();
if (!smsRes.ok) throw new Error(sms.error);
console.log(calls.totals.minutes, sms.totals.sent);
```
```python Python
calls = requests.get(
    "https://api.pozy.ai/v1/usage/calls",
    headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
    params={"since": "2026-10-01", "until": "2026-10-31", "groupBy": "number"},
).json()
print(calls["totals"]["minutes"], calls["totals"]["billableUSD"])
```

| Endpoint | Filters | Totals |
| --- | --- | --- |
| `GET /v1/usage/calls` | `since`, `until`, `channel` (`whatsapp`, `pstn`), `number`, `groupBy` (`day`, `number`, `channel`) | `calls`, `answered`, `minutes`, `billableUSD`, `brandedCalls`, `brandedCallUSD` |
| `GET /v1/usage/sms` | `since`, `until`, `number`, `groupBy` (`day`, `number`) | `sent`, `received`, `total` |

## Keep spend in check

- **X spend cap.** Set a monthly cap for X in Billing. At the cap, billable X calls pause until the 1st ([billing](https://pozy.ai/docs/billing/billing#x-spend-cap)).
- **Watch the projection.** `GET /v1/billing` returns `projectedThisPeriodCents`. Alert yourself when it passes a budget.
- **Alert on early charges.** The first early charge happens when the month's accrued usage reaches $10. The threshold then doubles after each early charge ($20, $40 and so on, up to $10,240), so a second or third early charge in one month means usage is climbing fast.
- **Per customer.** Run the `groupBy=profile` report nightly and compare each customer's cost with what you charge them.

`GET /v1/usage-stats` is an older form of the snapshot. It still works but is deprecated: use `GET /v1/usage`.

## Endpoints

| Endpoint | What it does |
| --- | --- |
| [`GET /v1/billing`](https://pozy.ai/docs/api/getBilling) | Account billing snapshot (plan, cycle, balance, caps, status) |
| [`GET /v1/billing/x-pricing`](https://pozy.ai/docs/api/getXApiPricing) | Get X API pricing table |
| [`GET /v1/usage`](https://pozy.ai/docs/api/getUsage) | Usage snapshot (default) or billed-spend metering (with params) |
| [`GET /v1/usage-stats`](https://pozy.ai/docs/api/getUsageStats) | Get plan and usage snapshot (plan, limits, payment status) |
| [`GET /v1/usage/calls`](https://pozy.ai/docs/api/getCallsUsage) | Calling usage and cost |
| [`GET /v1/usage/sms`](https://pozy.ai/docs/api/getSmsUsage) | SMS usage (volumes) |
