Credits
HTTP API routes for prepaid credit balance, usage spend, and top-up.
Org prepaid credit balance and usage spend for one billing cycle, plus credit
top-up: the HTTP mirror of ax credit. Amounts are USD prepaid
credits reported in micros (1 credit dollar = 1_000_000 micros).
| Route | Use | CLI equivalent |
|---|---|---|
GET /credits/balance | Org prepaid balance for one cycle (admin only). | ax credit balance --json |
GET /credits/spend | Usage spend for one cycle (members are self-scoped). | ax credit spend --json |
POST /credits/reload | Start a credit top-up and get a Checkout URL (admin only). | ax credit reload --json |
Every route takes org_id (required only when the key can see several orgs).
Parameters are optional unless marked required.
Payment itself never happens over this API. Reload returns a hosted Stripe
Checkout URL that a human opens in a browser, and no card data passes through
/api/v1.
Authorization
| Who | GET /credits/balance | GET /credits/spend | POST /credits/reload |
|---|---|---|---|
| Org admin | Full org balance for the selected cycle. | Org spend; may group or filter by user or experiment. | May start a top-up. |
| Org member | 403 permission_denied. | Personal spend only, always scoped to the key's user. | 403 permission_denied. |
Member-restricted spend parameters return 403 permission_denied:
group_by=user, and user= naming anyone else. The denial is identical either
way, so it never reveals whether that user exists.
Billing period
The two read routes select one org UTC calendar billing cycle with period:
| Value | Meaning |
|---|---|
current | Default. Cycle containing now; if none is open, the newest cycle. |
previous | Cycle immediately before the current selection. |
YYYY-MM | Cycle whose period start falls in that UTC calendar month (strict two-digit month). |
An invalid token returns 400 invalid_argument. A valid period with no matching
cycle returns 404 not_found.
A billing cycle follows your plan anniversary, not the calendar, so one month can
contain two cycles: a mid-month plan change starts a new one. YYYY-MM then
selects the cycle you ended that month on, and the earlier one is what previous
returns while that cycle is current. Read periodStart / periodEnd on the
response to see exactly which window answered.
Money fields
Every amount is decimal integer micros as a JSON string, never a JSON
number, so large values stay exact for scripts. Divide by 1000000 for dollars,
using a decimal or big-integer type rather than a float.
Credit expiry
The balance buckets do not have the same lifetime:
| Bucket | Lifetime |
|---|---|
Base plan credit (freeBalanceMicros) | $25 issued every billing cycle, on every plan. Expires when that cycle ends, so it does not roll over. |
Increment plan credit (planPaidBalanceMicros) | The further $125 a Pro subscription adds each cycle. Stays spendable for two billing cycles after it is granted, even if you cancel in between. |
On-demand credits (paidBalanceMicros) | Bought outright. Never expire. |
Credits are spent in expiry order: base plan credit first, then increment plan
credit, then on-demand credit. totalBalanceMicros therefore mixes money with
different lifetimes; read the per-bucket fields if you need to know what is
durable.
Changing plan never writes credit off. Upgrading mid-cycle keeps your current base credit to its original expiry and adds a prorated base top-up that aligns you to your new billing cycle, alongside the full increment. Downgrading forfeits nothing: increment credit you were already granted stays spendable until its own expiry.
GET /api/v1/credits/balance
Remaining org prepaid credit for one billing cycle, by bucket. Org admin only.
curl -H "Authorization: Bearer $AX_API_KEY" \
"https://app.514.ax/api/v1/credits/balance?period=previous"| Parameter | What it does |
|---|---|
period | Billing cycle selector (default current). |
| Response field | Meaning |
|---|---|
periodStart, periodEnd | Selected cycle window (RFC 3339; end is exclusive). |
billingCycleId | Cycle id. |
asOf | Instant the balance is computed for: now while the cycle is open, cycle end once closed. |
currency | Currency code (USD). |
totalBalanceMicros | Remaining prepaid credit at asOf. |
freeBalanceMicros, planPaidBalanceMicros, paidBalanceMicros | The same remaining credit broken out by bucket. |
cycleFundedMicros | Funding attached to this cycle for the whole cycle, not truncated to asOf. |
GET /api/v1/credits/spend
Usage spend for one billing cycle. Admins see org-wide totals, optionally grouped or filtered; members receive their own spend.
Member scoping here is a default view, not a confidentiality boundary. It
reflects what you usually want to see (your own spend) and matches the Usage
page and ax credit spend. Runs and experiments are org-visible to every
member by default, so per-teammate spend is not treated as confidential within
an organization. The boundaries that are enforced: your organization (no
cross-org reads), and org financial state such as credit balances, which is
admin-only.
curl -H "Authorization: Bearer $AX_API_KEY" \
"https://app.514.ax/api/v1/credits/spend?group_by=experiment&include_byok=true"| Parameter | What it does |
|---|---|
period | Billing cycle selector (default current). |
group_by | experiment or user: break spend into series. user is admin only. |
experiment | Limit to one experiment (id or exact display name). |
user | Limit to one user (Clerk user id or email). Admin only for another identity. |
include_byok | true or false (default false). Include BYOK attribution totals. |
Managed spend is 514-managed usage cost for the cycle: priced managed model
usage plus infrastructure run charges. BYOK attribution is reported
separately when include_byok=true and is never added into managed spend.
Without it, BYOK totals are "0".
| Response field | Meaning |
|---|---|
periodStart, periodEnd, billingCycleId, currency | Selected cycle metadata. |
groupBy, experimentId, userId | Echo of the effective grouping and filters after authorization (empty when unused; userId is the caller for members). |
totalManagedSpendMicros | Sum of managed spend across the result set. |
totalByokAttributionMicros | Sum of BYOK attribution when requested, else "0". |
series | Breakdown rows: key, label, managedSpendMicros, byokAttributionMicros. Ungrouped responses return a single total row. |
Examples:
# Your own spend for the current cycle (any member)
curl -H "Authorization: Bearer $AX_API_KEY" \
"https://app.514.ax/api/v1/credits/spend"
# Admin: one teammate in the prior cycle
curl -H "Authorization: Bearer $AX_API_KEY" \
"https://app.514.ax/api/v1/credits/spend?user=dana@acme.com&period=previous"
# Filter to one experiment by name
curl -H "Authorization: Bearer $AX_API_KEY" \
"https://app.514.ax/api/v1/credits/spend?experiment=gateway-smoke&group_by=experiment"POST /api/v1/credits/reload
Buy prepaid credit for the org. Org admin only.
The platform mints a hosted Stripe Checkout session (mode: payment), the
same session the web Buy credits flow creates, and returns its URL. Payment
always completes in a browser on Stripe: this route never accepts card details,
and credit is posted by the Stripe webhook once the session is paid, not when
this call returns.
curl -X POST -H "Authorization: Bearer $AX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"amountUsd": "50"}' \
"https://app.514.ax/api/v1/credits/reload"| Body field | What it does |
|---|---|
amountUsd | Required. Credit amount in USD as a string with at most two decimal places ("50", "49.99"). |
The amount must be between $5 and $5,000, the same bounds as the web
custom-amount purchase and ax credit reload. Malformed amounts (negatives,
more than two decimals, exponents, thousands separators, JSON numbers) return
400 invalid_argument. An org_id in the body is ignored; the org comes from
the key, with the org_id query parameter when the key can see several orgs.
| Response field | Meaning |
|---|---|
url | Hosted Stripe Checkout URL a human must open to pay. |
sessionId | Stripe Checkout Session id (cs_…). |
orgId | Org the credit will be posted to. |
amountUsd | Canonical two-decimal echo of the accepted amount ("50.00"). |
amountMicros | Credit posted once the session is paid, in micros. |
currency | Lowercase ISO currency of the session ("usd"). |
An agent driving the platform over HTTP should hand the returned url to a
human to complete payment, then poll
GET /credits/balance; the balance moves only
after Stripe reports the session paid, usually within a few minutes.