API overview

Conventions shared by every endpoint: base URL, authentication, request and response format, ids, metadata and versioning.

https://api.borga.is

The Borga API is REST over HTTPS with JSON bodies. It follows the conventions most developers know from Stripe: predictable resource URLs, snake_case fields, prefixed ids, cursor pagination and idempotent POSTs. Where Borga's domain differs, for example bank invoices and accounting sync, the API says so rather than bending the concept.

Authentication

Send a secret key as a bearer token. The key identifies your merchant and its mode; nothing else is needed.

Authorization: Bearer sk_test_…

Publishable keys (pk_…) may only call POST /v1/payment_sessions with mode: "embedded", from an allowed origin. Everything else needs a secret key. See Authentication.

Requests

  • Bodies are JSON with Content-Type: application/json.
  • Amounts are integers in the currency's smallest unit. ISK has none, so 1990 is 1.990 kr.; euro uses cents. Supported currencies:

    ISK (no minor unit), EUR, USD, GBP, DKK, NOK, SEK

  • Timestamps are ISO 8601 strings in UTC, for example 2026-09-07T12:04:31.512Z.
  • Unknown fields are ignored; wrong types return validation_failed.
  • POST requests should carry an Idempotency-Key. See Idempotency.

Responses

Objects are returned as flat JSON with related objects referenced by id ("customer": "cus_…"). A few objects carry an object field naming their type; most do not, so key off the id prefix instead. Lists come back as { "data": [...], "has_more": true }; see Pagination.

Every response includes an X-Request-Id header. Errors share one envelope with type, code, message, optional param, doc_url and request_id; see Errors.

Object ids

Ids are random strings with a type prefix, so a pay_… is always a payment wherever it shows up.

PrefixObject
pay_Payment
ps_Payment session
pm_Payment method (saved card)
ref_Refund
cus_Customer
cprt_Customer portal link
prod_Product
price_Price
sub_Subscription
si_Subscription item
inv_Invoice
ili_Invoice line
ii_Invoice item (one-off charge)
cn_Credit note
mtr_Meter
ue_Usage event
cmt_Customer meter balance
evt_Webhook event
we_Webhook endpoint
merch_Merchant
key_API key
al_Accounting connection
be_Billing ledger entry
pcs_Payment session client secret (embedded checkout, returned once)
sk_test_ / sk_live_Secret API key
pk_test_ / pk_live_Publishable API key

Metadata

Most objects accept a metadata object of your own keys and values. Borga stores it and returns it unchanged, never interprets it, and copies it from a payment session to the payment it creates. Use it for order numbers, internal ids and anything you want to see in webhooks.

Test and live

Mode is a property of the key. Test objects and live objects never mix, and live keys only work after going live. Everything on these pages behaves identically in both modes.

Versioning

The API is versioned in the path (/v1). Backwards-compatible changes (new fields, new endpoints, new event types, new error codes) ship without notice. Breaking changes would get a new path version with a migration period. Write clients to ignore fields and codes they do not recognise.

Dashboard-only configuration

API keys, webhook endpoints, allowed redirect domains, the accounting connection and bank-invoice settings are managed in the dashboard, not through API keys. Calling those routes with an API key returns wrong_auth_method.

Endpoints