# API overview

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

Source: https://docs.borga.is/api

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

```http
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](/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: _(Currencies table: see the HTML page)_
- 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](/api/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](/api/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](/errors).

## Object ids

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

_(IdPrefixes table: see the HTML page)_

## 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](/go-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](https://dashboard.borga.is), not through API keys. Calling those routes with an API key returns `wrong_auth_method`.

## Endpoints

- [Payment sessions](/api/payment-sessions): Create checkouts, hosted or embedded.
- [Payments](/api/payments): Read payment status and details.
- [Refunds](/api/refunds): Return money, fully or partially.
- [Payment methods](/api/payment-methods): Saved cards attached to customers.
- [Customers](/api/customers): People and companies you bill.
- [Customer portals](/api/customer-portals): Payer-facing invoice history links.
- [Products and prices](/api/products): Your catalogue.
- [Subscriptions](/api/subscriptions): Recurring billing.
- [Invoices](/api/invoices): Booked invoices and credit notes.
- [Meters and usage](/api/meters): Usage-based billing.
