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

# Prices API — set pricing for your products

> Create one-time and recurring prices for your products. Supports flat-rate, tiered, and metered usage pricing with graduated or volume tier modes.

A price defines how much and how often you charge for a product. Each price belongs to a product and specifies a `type` of either `one_time` or `recurring`. Recurring prices support flexible intervals, tiered pricing structures, and metered usage billing. Once a price is created, its core monetary fields are immutable — create a new price if you need to change the amount.

***

## Create a price

`POST /v1/prices`

Creates a new price for an existing product.

### Request parameters

<ParamField body="product" type="string" required>
  The ID of the product this price belongs to (e.g. `prod_xxx`).
</ParamField>

<ParamField body="currency" type="string">
  Three-letter ISO 4217 currency code (e.g. `ISK`, `EUR`, `USD`). Defaults to the merchant's default currency.
</ParamField>

<ParamField body="type" type="string" required>
  Pricing type. One of `one_time` or `recurring`.
</ParamField>

<ParamField body="unit_amount" type="number">
  Price per unit in the currency's smallest unit. Minimum value is `0`. Required when `tiers_mode` is not set.
</ParamField>

<ParamField body="recurring" type="object">
  Required when `type` is `recurring`. Defines the billing interval.

  <Expandable title="properties">
    <ParamField body="interval" type="string" required>
      Billing interval. One of `day`, `week`, `month`, or `year`.
    </ParamField>

    <ParamField body="interval_count" type="number">
      Number of intervals between billing cycles. For example, `interval: "month"` and `interval_count: 3` bills every three months. Defaults to `1`.
    </ParamField>

    <ParamField body="usage_type" type="string">
      How usage is determined for metered prices. One of `licensed` (fixed quantity per period) or `metered` (sum of usage events). Defaults to `licensed`.
    </ParamField>

    <ParamField body="aggregate_usage" type="string">
      How usage events are aggregated for metered prices. One of `sum`, `max`, or `last_during_period`.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="tiers_mode" type="string">
  Enables tiered pricing. One of `graduated` (each tier applies to usage within that range) or `volume` (the tier price applies to the entire quantity based on total usage).
</ParamField>

<ParamField body="tiers" type="object[]">
  Array of tier objects. Required when `tiers_mode` is set.

  <Expandable title="tier properties">
    <ParamField body="up_to" type="number">
      Upper bound for this tier. Use `null` to indicate the final open-ended tier.
    </ParamField>

    <ParamField body="unit_amount" type="number">
      Price per unit within this tier.
    </ParamField>

    <ParamField body="flat_amount" type="number">
      Fixed fee charged for this tier regardless of quantity.
    </ParamField>
  </Expandable>
</ParamField>

<ParamField body="meter" type="string">
  ID of the meter to use for metered usage billing. Required when `recurring.usage_type` is `metered`.
</ParamField>

<ParamField body="included_units" type="number">
  Number of units included in the base price before metered usage billing begins.
</ParamField>

<ParamField body="accounting_code" type="string">
  GL account code to associate with this price for accounting export.
</ParamField>

<ParamField body="metadata" type="object">
  Set of key-value pairs you can attach to the price. Values must be strings.
</ParamField>

<Tabs>
  <Tab title="One-time price">
    <RequestExample>
      ```bash cURL theme={null}
      curl --request POST \
        --url https://api.borga.is/v1/prices \
        --header "Authorization: Bearer sk_live_..." \
        --header "X-Merchant-Id: mer_xxx" \
        --header "Content-Type: application/json" \
        --data '{
          "product": "prod_01hx9z3k2mfq7nbvd4cw8ej5rt",
          "currency": "ISK",
          "type": "one_time",
          "unit_amount": 9900,
          "accounting_code": "4000"
        }'
      ```
    </RequestExample>
  </Tab>

  <Tab title="Recurring price">
    <RequestExample>
      ```bash cURL theme={null}
      curl --request POST \
        --url https://api.borga.is/v1/prices \
        --header "Authorization: Bearer sk_live_..." \
        --header "X-Merchant-Id: mer_xxx" \
        --header "Content-Type: application/json" \
        --data '{
          "product": "prod_01hx9z3k2mfq7nbvd4cw8ej5rt",
          "currency": "ISK",
          "type": "recurring",
          "unit_amount": 4990,
          "recurring": {
            "interval": "month",
            "interval_count": 1,
            "usage_type": "licensed"
          },
          "accounting_code": "4000"
        }'
      ```
    </RequestExample>
  </Tab>
</Tabs>

### Response fields

<ResponseField name="id" type="string" required>
  Unique identifier for the price (e.g. `price_xxx`).
</ResponseField>

<ResponseField name="product" type="string" required>
  ID of the associated product.
</ResponseField>

<ResponseField name="currency" type="string" required>
  Three-letter ISO 4217 currency code.
</ResponseField>

<ResponseField name="type" type="string" required>
  Pricing type. One of `one_time` or `recurring`.
</ResponseField>

<ResponseField name="unit_amount" type="number">
  Price per unit. `null` when `tiers_mode` is set.
</ResponseField>

<ResponseField name="recurring" type="object">
  Recurring billing configuration. `null` for one-time prices.

  <Expandable title="properties">
    <ResponseField name="interval" type="string" required>
      Billing interval.
    </ResponseField>

    <ResponseField name="interval_count" type="number" required>
      Number of intervals between billing cycles.
    </ResponseField>

    <ResponseField name="usage_type" type="string" required>
      Usage type: `licensed` or `metered`.
    </ResponseField>

    <ResponseField name="aggregate_usage" type="string">
      Aggregation method for metered usage.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="tiers_mode" type="string">
  Tier mode: `graduated` or `volume`. `null` if not using tiered pricing.
</ResponseField>

<ResponseField name="tiers" type="object[]">
  Array of tier configuration objects. `null` if not using tiered pricing.
</ResponseField>

<ResponseField name="meter" type="string">
  ID of the associated meter, if applicable.
</ResponseField>

<ResponseField name="active" type="boolean" required>
  Whether the price is currently active.
</ResponseField>

<ResponseField name="metadata" type="object">
  Key-value pairs attached to the price.
</ResponseField>

<ResponseExample>
  ```json 201 theme={null}
  {
    "id": "price_01hx9z3k2mfq7nbvd4cw8ej5rt",
    "product": "prod_01hx9z3k2mfq7nbvd4cw8ej5rt",
    "currency": "ISK",
    "type": "recurring",
    "unit_amount": 4990,
    "recurring": {
      "interval": "month",
      "interval_count": 1,
      "usage_type": "licensed",
      "aggregate_usage": null
    },
    "tiers_mode": null,
    "tiers": null,
    "meter": null,
    "active": true,
    "metadata": {},
    "created_at": "2026-04-29T10:15:00Z"
  }
  ```
</ResponseExample>

***

## List prices

`GET /v1/prices`

Returns a paginated list of prices, ordered by creation date descending.

### Query parameters

<ParamField query="product" type="string">
  Filter prices by product ID.
</ParamField>

<ParamField query="starting_after" type="string">
  Cursor for pagination. Pass the `id` of the last price from the previous page to retrieve the next page.
</ParamField>

<ParamField query="limit" type="number">
  Maximum number of prices to return per page.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request GET \
    --url "https://api.borga.is/v1/prices?product=prod_01hx9z3k2mfq7nbvd4cw8ej5rt&limit=20" \
    --header "Authorization: Bearer sk_live_..." \
    --header "X-Merchant-Id: mer_xxx"
  ```
</RequestExample>

### Response fields

<ResponseField name="data" type="object[]" required>
  Array of price objects.
</ResponseField>

<ResponseField name="has_more" type="boolean" required>
  Whether more prices exist beyond this page.
</ResponseField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": [
      {
        "id": "price_01hx9z3k2mfq7nbvd4cw8ej5rt",
        "product": "prod_01hx9z3k2mfq7nbvd4cw8ej5rt",
        "currency": "ISK",
        "type": "recurring",
        "unit_amount": 4990,
        "recurring": {
          "interval": "month",
          "interval_count": 1,
          "usage_type": "licensed",
          "aggregate_usage": null
        },
        "active": true,
        "metadata": {}
      }
    ],
    "has_more": false
  }
  ```
</ResponseExample>

***

## Retrieve a price

`GET /v1/prices/{id}`

Retrieves the details of an existing price.

### Path parameters

<ParamField path="id" type="string" required>
  The ID of the price to retrieve.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request GET \
    --url https://api.borga.is/v1/prices/price_01hx9z3k2mfq7nbvd4cw8ej5rt \
    --header "Authorization: Bearer sk_live_..." \
    --header "X-Merchant-Id: mer_xxx"
  ```
</RequestExample>

### Response fields

Returns a price object. See [create a price](#create-a-price) for the full field reference.

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "price_01hx9z3k2mfq7nbvd4cw8ej5rt",
    "product": "prod_01hx9z3k2mfq7nbvd4cw8ej5rt",
    "currency": "ISK",
    "type": "recurring",
    "unit_amount": 4990,
    "recurring": {
      "interval": "month",
      "interval_count": 1,
      "usage_type": "licensed",
      "aggregate_usage": null
    },
    "tiers_mode": null,
    "tiers": null,
    "meter": null,
    "active": true,
    "metadata": {},
    "created_at": "2026-04-29T10:15:00Z"
  }
  ```
</ResponseExample>

***

## Update a price

`PATCH /v1/prices/{id}`

Updates a price. Only `active`, `accounting_code`, and `metadata` can be modified after creation. To change the amount, currency, or interval, create a new price.

### Path parameters

<ParamField path="id" type="string" required>
  The ID of the price to update.
</ParamField>

### Request parameters

<ParamField body="active" type="boolean">
  Set to `false` to deactivate this price. Deactivating does not affect subscriptions already using it.
</ParamField>

<ParamField body="accounting_code" type="string">
  Updated GL account code.
</ParamField>

<ParamField body="metadata" type="object">
  Updated metadata. Replaces the existing metadata object entirely.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl --request PATCH \
    --url https://api.borga.is/v1/prices/price_01hx9z3k2mfq7nbvd4cw8ej5rt \
    --header "Authorization: Bearer sk_live_..." \
    --header "X-Merchant-Id: mer_xxx" \
    --header "Content-Type: application/json" \
    --data '{
      "active": false,
      "accounting_code": "4001"
    }'
  ```
</RequestExample>

### Response fields

Returns the updated price object. See [retrieve a price](#retrieve-a-price) for the full field reference.

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "price_01hx9z3k2mfq7nbvd4cw8ej5rt",
    "product": "prod_01hx9z3k2mfq7nbvd4cw8ej5rt",
    "currency": "ISK",
    "type": "recurring",
    "unit_amount": 4990,
    "recurring": {
      "interval": "month",
      "interval_count": 1,
      "usage_type": "licensed",
      "aggregate_usage": null
    },
    "tiers_mode": null,
    "tiers": null,
    "meter": null,
    "active": false,
    "metadata": {},
    "created_at": "2026-04-29T10:15:00Z"
  }
  ```
</ResponseExample>
