Usage API
Read your current quota position without spending any of it.
GET /api/usage reports where your organization stands in the current minute,
the current month and — when one is running — the current trial. It is
authenticated with the same API key as the gateway, and reading it costs no
units.
curl https://app.upapi.io/api/usage \
-H 'x-api-key: upapi_YOUR_KEY'The endpoint is also reachable through the gateway host, which is convenient if
your client is already configured for api.upapi.io:
curl https://api.upapi.io/usage \
-H 'x-api-key: upapi_YOUR_KEY'This one is a GET
Operations are always POST. /api/usage is a platform endpoint rather than an operation, and it
is a GET. It accepts an API key only — a browser session will not authenticate it.
Response
{
"plan": "Pro",
"planSlug": "pro",
"status": "ACTIVE",
"rpmLimit": 300,
"monthlyLimit": 500000,
"usedThisMinute": 4,
"usedThisMonth": 128340,
"remainingMinute": 296,
"remainingMonth": 371660,
"units": { "used": 128340, "limit": 500000, "remaining": 371660 },
"resetAt": "2026-08-06T12:01:00.000Z",
"hostedFunctions": { "used": 2, "limit": 15 },
"computeSeconds": { "used": 812, "limit": 50000 }
}| Field | Meaning |
|---|---|
plan, planSlug | Display name and slug of the active plan |
status | Subscription status — FREE, TRIALING, ACTIVE, … |
rpmLimit, usedThisMinute, remainingMinute | The per-minute burst window, counted in requests |
monthlyLimit, usedThisMonth, remainingMonth | The monthly budget, counted in weighted units |
units | The same monthly figures grouped together |
resetAt | When the current minute window rolls over |
hostedFunctions | Deployed functions against your plan's allowance |
computeSeconds | Hosted-function compute consumed this month |
Minutes count requests, months count units
usedThisMinute is a raw request count. usedThisMonth and every units figure are weighted. A
single Instagram call moves the first by 1 and the second by 15 — see Rate limits.
The trial block
While a trial is live, one extra key appears:
{
"trial": {
"unitCap": 50000,
"unitsUsed": 12800,
"unitsRemaining": 37200,
"endsAt": "2026-08-20T09:14:00.000Z"
}
}When no trial is running, trial is omitted entirely rather than sent with
zeroes. That is deliberate, so clients can feature-detect:
const usage = await res.json();
if ('trial' in usage) {
// On a trial: both the clock and the unit budget apply.
showTrialBanner(usage.trial.unitsRemaining, usage.trial.endsAt);
}Testing usage.trial.unitsRemaining > 0 without the guard throws off-trial.