Search documentation

Search the Fumadocs-backed documentation index.

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).

RouteUseCLI equivalent
GET /credits/balanceOrg prepaid balance for one cycle (admin only).ax credit balance --json
GET /credits/spendUsage spend for one cycle (members are self-scoped).ax credit spend --json
POST /credits/reloadStart 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

WhoGET /credits/balanceGET /credits/spendPOST /credits/reload
Org adminFull org balance for the selected cycle.Org spend; may group or filter by user or experiment.May start a top-up.
Org member403 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:

ValueMeaning
currentDefault. Cycle containing now; if none is open, the newest cycle.
previousCycle immediately before the current selection.
YYYY-MMCycle 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:

BucketLifetime
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"
ParameterWhat it does
periodBilling cycle selector (default current).
Response fieldMeaning
periodStart, periodEndSelected cycle window (RFC 3339; end is exclusive).
billingCycleIdCycle id.
asOfInstant the balance is computed for: now while the cycle is open, cycle end once closed.
currencyCurrency code (USD).
totalBalanceMicrosRemaining prepaid credit at asOf.
freeBalanceMicros, planPaidBalanceMicros, paidBalanceMicrosThe same remaining credit broken out by bucket.
cycleFundedMicrosFunding 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"
ParameterWhat it does
periodBilling cycle selector (default current).
group_byexperiment or user: break spend into series. user is admin only.
experimentLimit to one experiment (id or exact display name).
userLimit to one user (Clerk user id or email). Admin only for another identity.
include_byoktrue 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 fieldMeaning
periodStart, periodEnd, billingCycleId, currencySelected cycle metadata.
groupBy, experimentId, userIdEcho of the effective grouping and filters after authorization (empty when unused; userId is the caller for members).
totalManagedSpendMicrosSum of managed spend across the result set.
totalByokAttributionMicrosSum of BYOK attribution when requested, else "0".
seriesBreakdown 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 fieldWhat it does
amountUsdRequired. 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 fieldMeaning
urlHosted Stripe Checkout URL a human must open to pay.
sessionIdStripe Checkout Session id (cs_…).
orgIdOrg the credit will be posted to.
amountUsdCanonical two-decimal echo of the accepted amount ("50.00").
amountMicrosCredit posted once the session is paid, in micros.
currencyLowercase 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.