Agent payments — discover prices, survive 402, top up, retry
The full prepaid-credit payment loop for autonomous agents — price discovery at /api/v1/pricing, the machine-readable 402 recovery contract, the human top-up handover, and balance visibility on every metered response.
[Cite this as: Apier.no Docs v0.1.0 — last updated 2026-07-19]
Apier's company-data reads are metered against a prepaid credit balance held per API key. This guide is written for machine consumption first: exact field names, exact status codes, and complete example bodies, so an agent (or the developer wiring one) can implement the whole payment loop without guesswork. Every amount on this API is a whole-øre integer (100 øre = NOK 1) — no floats, no fractional øre, ever.
One honesty note up front: while credit enforcement runs dark (the launch
default), metered calls are not charged and a 402 is impossible — those
responses carry the X-Credit-Check: shadow header instead. Everything below
describes the live-enforcement contract, which is also what the
enforcement.live field on /api/v1/pricing reports. That pricing response
is served Cache-Control: no-store, so the flag is never stale out of a
shared cache — but treat it as best-effort discovery: the authoritative
charging signal is always the metered response itself (X-Credit-Check: shadow = not charged; X-Credits-* headers or a 402 body = enforcement
live), never a previously fetched price list.
Two ways to pay — subscriptions and prepaid credits
When billing goes live there are two payment methods. A monthly subscription tier bundles a set number of API calls into its fixed fee. Prepaid credits are a balance you top up, from which each metered call draws its cost (50 øre for a company-data read).
If an account holds both, the subscription's included calls are consumed first; credits are only drawn once those included calls are exhausted. Unused credits stay on the account. This quota-first ordering is enforced from billing go-live — during the beta every call is free and nothing is charged, so treat the credit loop below as the live-enforcement contract. Brief your operator accordingly: an account on a subscription can still have plenty of included calls left even when its prepaid balance reads zero, so a zero balance is not by itself a reason to stop or to request a top-up until the metered response actually returns a 402.
1. Discover prices before paying — GET /api/v1/pricing
GET https://apier.no/api/v1/pricing is public and keyless: an agent can
price a workflow before it holds an API key or a balance. The response is
derived from the canonical pricing configuration the 402 meter enforces —
there is no second price table anywhere in the system. A previously fetched
price can still become stale after a pricing change, so the per-call metered
response (not a stored price list) remains the authoritative charging signal.
{
"success": true,
"data": {
"schema_version": "1.0.0",
"currency": "NOK",
"credit_unit": "Whole øre (1 øre = NOK 0.01). Every cost, balance, and top-up amount on this API is a whole-øre integer — no floats, no fractional øre.",
"metered_endpoints": [
{
"endpoint": "/api/v1/company/{org}/context",
"method": "GET",
"category": "rulebook_read",
"cost_ore": 50,
"mcp_tool": "get_company_context"
}
],
"enforcement": {
"live": true,
"authority_note": "Best-effort discovery signal. The authoritative charging signal is always the metered response itself: X-Credit-Check: shadow means the call was not charged; X-Credits-* headers or a 402 INSUFFICIENT_CREDITS body mean enforcement is live. Never infer charging behaviour from a previously fetched price list alone.",
"insufficient_balance_status": 402,
"insufficient_balance_error_code": "INSUFFICIENT_CREDITS",
"recovery_contract_fields": ["retryable", "fix_hint", "docs_url", "top_up_url", "balance_ore", "cost_ore"]
},
"balance_visibility": {
"rest_headers": ["X-Credits-Balance-Ore", "X-Credits-Cost-Ore", "X-Credits-Warning", "X-Credits-Warning-Threshold-Ore", "X-Credits-Topup-Url"],
"mcp_metadata_field": "metadata.credits",
"balance_endpoint": "/api/v1/account/credits/balance"
},
"low_balance_warning": {
"factor": 5,
"rule": "A warning is emitted when the post-debit balance is strictly below factor × the call's cost_ore."
},
"top_up": {
"min_ore": 5000,
"max_ore": 1000000,
"top_up_url": "https://apier.no/dashboard/billing"
},
"how_to_pay_guide": "https://apier.no/docs/guides/agent-payments"
}
}The list above is truncated to one metered endpoint for readability — the live
response enumerates every metered endpoint. MCP tools inherit metering through
their REST forward (one debit point), so the mcp_tool name next to each
endpoint costs exactly the same as the endpoint itself, and every metered MCP
tool's description also states its own cost.
2. Authenticate
Metered endpoints require an API key in the Authorization header:
curl -H "Authorization: Bearer apier_test_<your_key_here>" \
https://apier.no/api/v1/company/999999999/contextA brand-new key has a balance of 0 øre — authoritatively zero, not unknown. Check any key's own balance at any time (this read is deliberately scope-exempt and never debits):
curl -H "Authorization: Bearer apier_test_<your_key_here>" \
https://apier.no/api/v1/account/credits/balance3. Interpret the 402 — the machine-readable recovery contract
With an insufficient balance, a metered call returns HTTP 402 with
error_code: "INSUFFICIENT_CREDITS". Nothing was charged: the balance is
checked-and-debited atomically before the handler runs, so an insufficient
balance leaves both the balance and the ledger untouched, deterministically.
A complete example 402 body:
{
"success": false,
"error_code": "INSUFFICIENT_CREDITS",
"explanation": {
"summary": "Forhåndsbetalt kredittsaldo er for lav for dette kallet.",
"summary_en": "Prepaid credit balance is too low for this call.",
"why": "Dette endepunktet koster 50 øre per kall, men saldoen på API-nøkkelen er 0 øre. Ingen belastning er gjort.",
"why_en": "This endpoint costs 50 øre per call, but the API key's balance is 0 øre. Nothing was charged.",
"fix_steps": [
"Fyll på kredittsaldoen fra faktureringssiden (se top_up_url).",
"Prøv forespørselen på nytt etter påfyll."
],
"fix_steps_en": [
"Top up the credit balance from the billing page (see top_up_url).",
"Retry the request after topping up."
]
},
"retryable": false,
"fix_hint": "Prepaid balance too low — top up (see top_up_url), then retry the request.",
"fix_hint_en": "Prepaid balance too low — top up (see top_up_url), then retry the request.",
"docs_url": "https://apier.no/docs/guides/agent-payments",
"top_up_url": "https://apier.no/dashboard/billing",
"balance_ore": 0,
"cost_ore": 50,
"_meta": {
"rulebook_version": "1.0.0",
"data_freshness": "2026-07-18T12:00:00.000Z",
"last_verified": "2026-07-18T12:00:00.000Z",
"source": "apier.no",
"schema_version": "1.4.0",
"response_timestamp": "2026-07-18T12:00:00.000Z",
"response_hash": "sha256:…"
}
}How an agent should read it:
retryable: false— an identical retry with an unchanged balance fails identically. Do not loop.balance_oreandcost_ore— compute the shortfall (cost_ore - balance_ore) and how much runway a given top-up buys.top_up_url— the human handover. Topping up is a payment action; a human completes it on the billing dashboard. Surface this URL to your operator verbatim.- After the top-up lands, retry the identical request. Reads are side-effect free; the retry is safe.
The related failure 503 CREDIT_CHECK_UNAVAILABLE (credit infrastructure
unreachable) is the opposite: retryable: true — wait a few seconds and retry
the identical call. Its body states the actual money outcome in
explanation.why_en.
4. Top up
Top-ups are made by a human on the billing dashboard at the exact
top_up_url the 402 body carries (byte-identical to the one
/api/v1/pricing and /api/v1/account/credits/balance advertise). Bounds:
min_ore: 5000 (NOK 50) to max_ore: 1000000 (NOK 10,000) per transaction.
Credits are granted exactly once per completed payment — replayed payment
events are deduplicated server-side.
5. Retry and read your balance on every success
After topping up, the identical request succeeds. Every successful metered
response reports the remaining balance in response headers (the JSON body is
never mutated post-hoc — its provenance response_hash must stay
re-verifiable):
HTTP/1.1 200 OK
X-Credits-Balance-Ore: 950
X-Credits-Cost-Ore: 50
X-Correlation-ID: 550e8400-e29b-41d4-a716-446655440000When the post-debit balance drops strictly below 5× the call's cost, a low-balance warning trio rides along — the agent's cue to request a top-up before the next 402:
HTTP/1.1 200 OK
X-Credits-Balance-Ore: 200
X-Credits-Cost-Ore: 50
X-Credits-Warning: low_balance
X-Credits-Warning-Threshold-Ore: 250
X-Credits-Topup-Url: https://apier.no/dashboard/billing6. The same contract over MCP
MCP tools forward to the REST endpoints, so the money semantics are identical — one debit point, one price. The envelope surfaces:
- Success:
metadata.creditson the tool result —{ "balance_ore": 200, "cost_ore": 50, "balance_warning": { "threshold_ore": 250, "remaining_ore": 200, "top_up_url": "https://apier.no/dashboard/billing" } }(balance_warningpresent only below the threshold). - Insufficient balance:
metadata.error_code: "INSUFFICIENT_CREDITS"withmetadata.retryable: false,metadata.remediation, and the same recovery fields —metadata.top_up_url,metadata.balance_ore,metadata.cost_ore.
Charging rules an agent can rely on
- A 402 never charges (checked-and-debited atomically before execution).
- A successful call (2xx) charges exactly its advertised
cost_ore. - Outcomes where no billable work was delivered — any 5xx, 403 (scope rejection), 404 (unknown company), 304 (revalidation hit) — are automatically refunded; the ledger nets to zero for those calls.
- Same input, same price: pricing is configuration, not negotiation (Rule 9 determinism extends to the meter).
Idempotency and safe retries
Make write requests retry-safe with the Idempotency-Key header — at-most-once execution, a 24-hour replay window, and the four reservation outcomes an agent must handle.
Billing — subscriptions, prepaid credits, invoices
How Apier billing works — the two payment methods (subscription tiers and prepaid credits), the quota-first spend order, invoices and receipts via Stripe, VAT (MVA), and how to change or cancel.