Skip to content
Apier
Apier.no
Guides

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/context

A 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/balance

3. 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_ore and cost_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-446655440000

When 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/billing

6. 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.credits on 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_warning present only below the threshold).
  • Insufficient balance: metadata.error_code: "INSUFFICIENT_CREDITS" with metadata.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).
Building with an LLM? Read llms.txt for agent-oriented integration guidance.