Skip to content

GET /v1/usage

Everything the account has used this period, what remains of its allowance and cap, and — on a keyless trial — how many of the 50 trial renders are left. Free, and safe to call before a large batch.

GET https://api.galleyrender.com/v1/usage
Authorization: Bearer glr_sk_…

Takes no parameters. It always reports the current period; there is no history endpoint.

Check usage shell
curl -sS https://api.galleyrender.com/v1/usage \
  -H "Authorization: Bearer $GALLEY_API_KEY"
Check usage javascript
// Node 22+. No dependencies — `fetch` is built in.
const res = await fetch("https://api.galleyrender.com/v1/usage", {
  headers: {
    authorization: `Bearer ${process.env.GALLEY_API_KEY}`,
  },
});

const usage = await res.json();
if (!res.ok) throw new Error(usage.error.message);

console.log(usage);
Check usage python
# Python 3.9+. Standard library only.
import json, os, urllib.request

req = urllib.request.Request(
    "https://api.galleyrender.com/v1/usage",
    headers={"Authorization": f"Bearer {os.environ['GALLEY_API_KEY']}"},
)

usage = json.load(urllib.request.urlopen(req))
print(usage)
Check usage — no key shell + json
# No API key. The first call mints a 50-render trial.
curl -sS https://mcp.galleyrender.com/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "usage",
      "arguments": {}
    }
  }'
200 OK — a paid account
{
"object": "usage",
"account": "acct_9k2pv3n8rc4t",
"plan": "starter",
"period": "2026-09",
"period_resets_on": "2026-10-01",
"renders": 412,
"billable_units": 690,
"meter_units": 1435,
"by_format": {
"pdf": { "billable_units": 498, "meter_units": 1245, "cost_usd": 7.47 },
"png": { "billable_units": 190, "meter_units": 190, "cost_usd": 1.14 },
"jpeg": { "billable_units": 2, "meter_units": 2, "cost_usd": 0.012 }
},
"cost_usd": 8.622,
"limits": {
"free_renders_per_month": 200,
"free_renders_remaining": null,
"monthly_spend_cap_usd": 50,
"spend_remaining_usd": 41.378
},
"trial": null,
"prices": {
"png_usd": 0.006,
"pdf_page_usd": 0.015,
"meter_event_name": "galley_render",
"meter_units_per": { "png": 1, "pdf_page": 2.5 }
},
"lifetime_renders": 3814,
"current_period": "2026-09"
}
FieldTypeMeaning
objectstringAlways usage.
accountstringThe account’s public id, acct_….
planstringfree, starter, growth or scale.
periodstringBilling period the numbers cover, YYYY-MM in UTC.
period_resets_onstringFirst day of the next period, YYYY-MM-DD.
rendersnumberBilled renders this period — one per metered render, cache hits excluded. Not the same as billable_units, because a 5-page PDF is one render and five units.
billable_unitsnumberUnits consumed this period: 1 per PNG/JPG, 1 per page of PDF. This is the number quotas, the free tier and the trial cap count.
meter_unitsnumberWhat Stripe has been told, which is a different number by design. See the metering note.
by_formatobjectThe same three numbers broken out per stored format. Keys are pdf, png and jpeg — note jpeg, not jpg, even though renders report jpg.
by_format.<format>.billable_unitsnumberUnits in that format.
by_format.<format>.meter_unitsnumberMeter units reported for that format.
by_format.<format>.cost_usdnumberCost in that format, rounded to six decimal places.
cost_usdnumberTotal cost this period in dollars, from our own meter, not Stripe’s invoice.
limits.free_renders_per_monthnumberThe account’s free-tier allowance in billable units. 200 by default; it can be raised per account.
limits.free_renders_remainingnumber | nullAllowance left, floored at 0. null on every plan except free — paid plans are governed by the spend cap instead.
limits.monthly_spend_cap_usdnumberThe account’s monthly spend cap. $50 by default.
limits.spend_remaining_usdnumberCap minus spend this period, floored at 0.
trialobject | nullnull unless the account is a keyless trial.
trial.renders_limitnumberLifetime billable-unit ceiling. 50.
trial.renders_usednumberUnits used across every period, not just this one.
trial.renders_remainingnumberrenders_limit − renders_used, floored at 0.
trial.upgradestringThe one sentence that lifts the limit.
prices.png_usdnumberDollars per PNG or JPG. 0.006.
prices.pdf_page_usdnumberDollars per PDF page. 0.015.
prices.meter_event_namestringThe Stripe billing meter these events are reported against: galley_render.
prices.meter_units_per.pngnumberMeter units reported per PNG/JPG. 1.
prices.meter_units_per.pdf_pagenumberMeter units reported per PDF page. 2.5.
lifetime_rendersnumberSucceeded renders on this account since it was created, all periods. Counts renders, not units.
current_periodstringThe current period at the moment of the call. Identical to period.
200 OK — a trial account
{
"object": "usage",
"account": "acct_4t8wq1mv2k9n",
"plan": "free",
"period": "2026-09",
"period_resets_on": "2026-10-01",
"renders": 6,
"billable_units": 11,
"meter_units": 21.5,
"by_format": {
"pdf": { "billable_units": 7, "meter_units": 17.5, "cost_usd": 0.105 },
"png": { "billable_units": 4, "meter_units": 4, "cost_usd": 0.024 }
},
"cost_usd": 0.129,
"limits": {
"free_renders_per_month": 200,
"free_renders_remaining": 189,
"monthly_spend_cap_usd": 50,
"spend_remaining_usd": 49.871
},
"trial": {
"renders_limit": 50,
"renders_used": 11,
"renders_remaining": 39,
"upgrade": "Call the `create_account` tool with an email to lift the trial limit."
},
"prices": {
"png_usd": 0.006,
"pdf_page_usd": 0.015,
"meter_event_name": "galley_render",
"meter_units_per": { "png": 1, "pdf_page": 2.5 }
},
"lifetime_renders": 6,
"current_period": "2026-09"
}

On a trial, trial.renders_remaining is the number that matters. The free-tier figures are also present and also true, but the lifetime ceiling bites first.

  • Cache hits are invisible here. A cache hit records no usage event, so it moves none of these counters. That is what “free” means.
  • Failed renders are not billed and do not appear either.
  • cost_usd is our own ledger, computed at $0.006 per PNG/JPG and $0.015 per PDF page. It is what the spend cap is enforced against. Your Stripe invoice is built from meter_units; the two agree by construction.
  • renders counts metered renders this period; lifetime_renders counts succeeded render rows ever. They are different questions and will not match.
Refuse to start a batch you cannot finish
units_left=$(curl -sS https://api.galleyrender.com/v1/usage \
-H "Authorization: Bearer $GALLEY_API_KEY" |
python3 -c 'import json,sys; u=json.load(sys.stdin); t=u["trial"]; print(t["renders_remaining"] if t else u["limits"]["free_renders_remaining"] or 10**9)')
echo "$units_left units left"

Remember that a PDF costs one unit per page, so a 50-item batch of three-page PDFs needs 150 units, not 50.

TypeStatusWhen
authentication_error401Missing, unknown or revoked key.