Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.borga.is/llms.txt

Use this file to discover all available pages before exploring further.

Usage-based billing charges customers for what they actually consume rather than a fixed recurring amount. Borga implements this through two primitives: meters, which define what to measure and how to aggregate it, and events, which are the raw usage records you send from your application. At the end of each billing period, Borga totals the events for each customer and generates an invoice based on the metered price you configured.
1

Create a meter

A meter defines the unit of measurement — what event name to listen for and how to aggregate the raw events into a billable quantity.
curl --request POST \
  --url https://api.borga.is/v1/meters \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "API Calls",
    "event_name": "api_call",
    "aggregate_type": "count"
  }'
The event_name links the meter to events you send later — any event with event_name: "api_call" is captured by this meter. The aggregate_type controls how Borga combines individual events into a single quantity for the billing period:
Aggregate typeBehaviour
countNumber of events received.
sumSum of the value field across all events.
maxHighest value seen across all events.
minLowest value seen across all events.
avgAverage value across all events.
uniqueCount of distinct value entries (deduplication).
For API call billing, count is the right choice. For data transfer billing, use sum and pass bytes in the value field.
2

Create a metered price

Create a price that references the meter. Set recurring.usage_type to "metered" so Borga knows to aggregate events rather than charge a fixed amount.
curl --request POST \
  --url https://api.borga.is/v1/prices \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID" \
  --header "Content-Type: application/json" \
  --data '{
    "product": "pro_01HXYZ",
    "currency": "ISK",
    "type": "recurring",
    "unit_amount": 1,
    "meter": "mtr_01HXYZ",
    "recurring": {
      "interval": "month",
      "usage_type": "metered"
    }
  }'
The unit_amount is the price per unit in whole ISK. In this example, each API call costs 1 kr. You can combine a metered price with a fixed base price by including both as items on the same subscription.
3

Create a subscription with the metered price

Create a subscription that includes the metered price as one of its items. The customer is not charged for usage until Borga invoices at the end of the billing period.
curl
curl --request POST \
  --url https://api.borga.is/v1/subscriptions \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID" \
  --header "Content-Type: application/json" \
  --data '{
    "customer": "cus_01HXYZ",
    "items": [
      { "price": "pri_01HXYZ", "quantity": 1 }
    ],
    "collection_method": "charge_automatically"
  }'
You can add both a fixed base price and the metered price to the same subscription to implement a “base fee plus usage” model:
{
  "customer": "cus_01HXYZ",
  "items": [
    { "price": "pri_BASE_PLAN" },
    { "price": "pri_METERED_CALLS" }
  ],
  "collection_method": "charge_automatically"
}
4

Ingest usage events

Send usage events from your application as they occur. Each event must include the event_name that matches your meter and the customer being charged.
curl --request POST \
  --url https://api.borga.is/v1/events \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID" \
  --header "Content-Type: application/json" \
  --data '{
    "event_name": "api_call",
    "customer": "cus_01HXYZ",
    "idempotency_key": "req_7a3f91b2c4d5e6f0",
    "timestamp": "2026-04-29T10:30:00Z",
    "metadata": {
      "endpoint": "/v1/payments",
      "method": "POST"
    }
  }'
Always include a unique idempotency_key on every event. If your application retries an event after a network failure, Borga uses the key to detect and discard the duplicate — preventing the customer from being billed twice for the same usage. A UUID or a hash of your internal request ID works well.
Use the batch endpoint (POST /v1/events/batch) when you need to ingest high volumes of events. Batching reduces API call overhead and is the recommended approach for ingesting events asynchronously from a queue.
5

Check quantities

At any point during the billing period, query the aggregated quantity for a customer to see how much usage they have accumulated.
curl --request GET \
  --url "https://api.borga.is/v1/meters/mtr_01HXYZ/quantities?customer=cus_01HXYZ&period_start=2026-04-01T00:00:00Z&period_end=2026-04-30T23:59:59Z" \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID"
The response includes the aggregated quantity for the given customer and time range. Use this to build usage dashboards or to preview what a customer will be charged at the end of the period.

Displaying usage to customers

You can expose usage data directly to your customers by querying GET /v1/meters/{id}/quantities from your server and surfacing the result in your application UI. This helps customers understand their consumption before the invoice arrives and reduces billing-related support requests.

Next steps

  • Subscriptions — set up fixed recurring plans alongside or instead of metered pricing
  • Webhooks — receive invoice.paid events when usage invoices are collected
  • Accounting link — sync invoices generated from metered usage to your accounting software