Pricing & billing
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 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.
curl https://api.pozy.ai/v1/usage \
-H "Authorization: Bearer $POZY_API_KEY"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);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"]){
"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.
#Spend over a range
Add any of the range parameters and the same endpoint returns metered spend instead, day by day and per product:
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.
curl "https://api.pozy.ai/v1/usage?range=cycle&granularity=total&groupBy=profile" \
-H "Authorization: Bearer $POZY_API_KEY"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);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"]){
"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:
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"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);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).
- Watch the projection.
GET /v1/billingreturnsprojectedThisPeriodCents. 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=profilereport 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 |
Account billing snapshot (plan, cycle, balance, caps, status) |
GET /v1/billing/x-pricing |
Get X API pricing table |
GET /v1/usage |
Usage snapshot (default) or billed-spend metering (with params) |
GET /v1/usage-stats |
Get plan and usage snapshot (plan, limits, payment status) |
GET /v1/usage/calls |
Calling usage and cost |
GET /v1/usage/sms |
SMS usage (volumes) |