Chrono Bank

Chrono Bank API

Overview

The Chrono Bank API lets your website, game, or app accept Chronos against a business account you control. You can take one-off payments, run recurring subscriptions (flat or usage-metered), and receive signed webhooks when something happens. Everything is plain JSON over HTTPS.

The base URL is https://chronobank.app. Vendor endpoints live under /api/v1/vendor.

Authentication

First create a business (Businesses → New), then open it and create an API token in the API tokens section. The token is shown once — store it like a password. Each token is bound to that one business.

Send it as a bearer token on every API call:

Authorization: Bearer cbv1_your_token_here

Tokens can be revoked at any time from the same page; revoke one immediately if it leaks.

One-time payments

Create an invoice for the amount you want to collect. You get back a pay_url — send the buyer there. They sign in to Chrono Bank, approve the payment, and (if you set a callback_url) get redirected back to you.

curl -X POST https://chronobank.app/api/v1/vendor/invoices \
  -H "Authorization: Bearer cbv1_…" \
  -d '{
    "amount_chronos": "50",
    "memo": "Sword of Testing",
    "external_reference": "order-42",
    "callback_url": "https://your-shop.example/return",
    "expires_in_seconds": 3600
  }'

The response includes the invoice id, its status (proposed), and the pay_url. After the buyer pays, we redirect them to callback_url?status=accepted&invoice_id=….

Confirm payment either by listening for the invoice.accepted webhook (recommended) or by polling:

curl https://chronobank.app/api/v1/vendor/invoices/INVOICE_ID \
  -H "Authorization: Bearer cbv1_…"
# status becomes "accepted"; payer_account_id and transaction_id are populated.

Deliver the goods once the payment is confirmed (see Things to know about reversals).

Subscriptions

A subscription is a standing authorization (a mandate): the customer approves it once, then you can charge them automatically each period. Create one and send the customer to the returned authorize_url.

Flat — a fixed amount per period. The first period is charged the moment the customer authorizes (so authorization fails if they can't cover it):

curl -X POST https://chronobank.app/api/v1/vendor/subscriptions \
  -H "Authorization: Bearer cbv1_…" \
  -d '{ "kind": "flat", "amount_chronos": "100", "interval_seconds": 2592000 }'

Metered — you report usage and we bill it at the end of each period. max_amount_chronos is the per-period ceiling the customer agrees to; a period that would exceed it fails (rather than overcharging):

curl -X POST https://chronobank.app/api/v1/vendor/subscriptions \
  -H "Authorization: Bearer cbv1_…" \
  -d '{ "kind": "metered", "unit_price_chronos": "0.5", "max_amount_chronos": "200", "interval_seconds": 2592000 }'

Report metered usage as it happens. idempotency_key makes a repeated report harmless:

curl -X POST https://chronobank.app/api/v1/vendor/subscriptions/SUB_ID/usage \
  -H "Authorization: Bearer cbv1_…" \
  -d '{ "quantity": "3", "idempotency_key": "req-2026-05-27-0001" }'

Other endpoints: GET /api/v1/vendor/subscriptions/{id} for status, GET …/{id}/charges for the charge history, and POST …/{id}/cancel to cancel. The customer can also cancel anytime from their own Subscriptions page.

If a charge fails for insufficient funds, we retry once a day for up to 7 days, then pause the subscription — you'll hear about each step over webhooks.

Webhooks

Add an endpoint URL in your business's Webhooks section and pick the events you want. We POST each event as JSON:

{
  "event": "invoice.accepted",
  "created_at": "2026-05-27T12:00:00Z",
  "data": { "invoice_id": "…", "transaction_id": "…", "amount_chronos": "50.000000000", "external_reference": "order-42" }
}

Every delivery carries a signature header so you can confirm it came from us:

X-ChronoBank-Signature: t=1779999999,v1=<hex>

To verify, compute HMAC-SHA256(signing_secret, "{t}.{raw_request_body}") and compare the hex digest to v1 (constant-time). You can also reject deliveries whose t is too old to blunt replay attempts. The signing secret is shown once when you create the endpoint.

Events: invoice.accepted, payment.reversed, subscription.activated, subscription.charged, subscription.charge_failed, subscription.canceled, subscription.paused. Delivery is best-effort — treat the invoice/subscription endpoints as the source of truth and use webhooks as the nudge.

Things to know

Reversals. Every payment has a reversal window during which the buyer can reverse it. If they do, you get a payment.reversed webhook. For irreversible digital goods, either deliver only after the window closes or be prepared to handle a reversal.

Demurrage applies to your revenue too. A business account's balance is subject to demurrage like any other — it's a property of the currency, not a fee we charge. A business is a vehicle for activity, not a savings vault; circulate revenue rather than letting it pool.