---
title: Upgrading
description: Step-by-step instructions for moving an integration from one API revision to the next.
---

Upgrading is a code change on your side followed by one header change. Nothing you receive changes
until you send the new `Api-Revision` value. The two steps are independent. Write the code, deploy
it, and set the header when you are ready.

Each section below is one hop between revisions. Start at the revision you send today and work
forward. If you send no `Api-Revision` header, you are on the oldest supported revision. You move off it on
the day that revision retires. Set the header as soon as you know which revision you want. Every
response tells you which one produced it:
```http
Api-Revision: 2026-08-21.auk
```

See [Versioning](/api-reference/versioning.md) for the revision list, the support window, and how the
header is resolved.

## Moving to 2026-09-01.bullfinch

Nearly all of this hop is one change: **every monetary amount is an integer in minor currency
units**. The major-unit field beside it is gone. The rest is a binding period that carries a unit,
and one endpoint that returned nothing new.

Every field named here is already served on `2026-08-21.auk`, so you can make all of these changes
and verify them before you touch the header.

**1. Read every amount from its minor-unit field**

A minor unit is the smallest unit of the currency — cents for `USD`, öre for `SEK` — so `$136.07`
is `13607`. The `currency` field sits on the same object and tells you which currency to divide by.
```json
// 2026-08-21.auk
{ "subtotal": 125.99, "taxAmount": 10.08, "total": 136.07, "currency": "USD" }

// 2026-09-01.bullfinch
{ "subtotalMinor": 12599, "taxAmountMinor": 1008, "totalMinor": 13607, "currency": "USD" }
```

Change the type in your own model while you are there. An integer count of minor units is exact. A
decimal amount that you parse into a binary float is not, and that is the reason for the change. Do
not store the new value in a float.

The [change inventory](#change-inventory) below has the complete list. Amounts appear in three
places:

- Order pricing: `subtotal`, `taxAmount` and `total`, on the summary and again under
  `recurringCosts` and `initialInvoice`.
- Line item pricing: `totalDiscounts`, `recurringAmount` and `initialInvoiceAmount`.
- Each discount and each tax breakdown entry: `amount`.

Each of these has a `*Minor` twin with the same meaning.

**2. Catalog prices and ILD balances**

Three amounts outside order pricing move the same way:

- `Price.netPrice` becomes `netPriceMinor`.
- `Price.currencyOptions` becomes `currencyOptionsMinor`.
- `UsageVoiceIldPackage.balance` becomes `balanceMinor`.

`currencyOptionsMinor` keeps the shape it had — a map from ISO currency code to the price in that
currency — with integer values:
```json
// 2026-08-21.auk
{ "netPrice": 29.99, "currencyOptions": { "SEK": 329.0, "EUR": 27.5 } }

// 2026-09-01.bullfinch
{ "netPriceMinor": 2999, "currencyOptionsMinor": { "SEK": 32900, "EUR": 2750 } }
```

**3. Read the binding period from bindingContract.duration**

`Price.boundMonths` is replaced by `Price.bindingContract.duration`, which carries the unit
alongside the count:
```json
// 2026-08-21.auk
{ "boundMonths": 12 }

// 2026-09-01.bullfinch
{ "bindingContract": { "duration": { "unit": "MONTHS", "value": 12 } } }
```

`bindingContract` is absent when the price has no binding period, exactly as `boundMonths` was, so
the check for "is this price bound" moves rather than changing shape.

Read `unit`. Do not assume it. `MONTHS` is its only value today. A client that reads `value` alone
will report a term in the wrong unit on the day another unit is added. That is why this field
replaced a bare month count.

**4. Stop calling POST /orders/{orderId}/calculate-price**

The platform calculates an order's price again each time the order changes, and the call that made
the change returns the result. `POST /orders`, `PUT /orders/{orderId}`, and the add-on and
line-item endpoints all carry the new `pricing` in their own response. A second call reads back a
value you already have.

When you need the current pricing without changing anything, read it off the order:
```bash
curl "{BASE_URL}/orders/{orderId}" \
  --header 'X-Api-Key: YOUR_API_KEY' \
  --header 'Api-Revision: 2026-09-01.bullfinch'
```

On `2026-09-01.bullfinch` the removed endpoint responds `404` with the error code
`endpoint_removed`. On `2026-08-21.auk` it keeps working until that revision is retired.

**5. Send the new revision and verify**

Send `Api-Revision: 2026-09-01.bullfinch` on a single non-production call and compare the response
against what you store. When it matches, set the header everywhere.
```bash
curl "{BASE_URL}/orders/{orderId}" \
  --header 'X-Api-Key: YOUR_API_KEY' \
  --header 'Api-Revision: 2026-09-01.bullfinch'
```

If you generate a client, generate it from
[the revision's own OpenAPI document](/openapi/2026-09-01.bullfinch.json). The reference on this
site always documents the current revision, so it stops matching you the moment a newer one ships.

## Change inventory

Every field and operation each revision changed. The steps above cover the same ground, in the order you do the work. Use this list to check your own integration.

### From 2026-08-21.auk to 2026-09-01.bullfinch

`2026-08-21.auk` is served until 2026-12-01.

Removed the deprecated order pricing amounts in major currency units. Read the integer `*Minor` field instead: `subtotalMinor`, `taxAmountMinor`, `totalMinor`, `totalDiscountsMinor`, `recurringAmountMinor`, `initialInvoiceAmountMinor`, `amountMinor`.

- `OrderLineItemPricing.initialInvoiceAmount`
- `OrderLineItemPricing.recurringAmount`
- `OrderLineItemPricing.subtotal`
- `OrderLineItemPricing.taxAmount`
- `OrderLineItemPricing.total`
- `OrderLineItemPricing.totalDiscounts`
- `OrderListItem.pricing.total`
- `OrderPricingDiscount.amount`
- `OrderPricingSummary.initialInvoice.subtotal`
- `OrderPricingSummary.initialInvoice.taxAmount`
- `OrderPricingSummary.initialInvoice.total`
- `OrderPricingSummary.recurringCosts.subtotal`
- `OrderPricingSummary.recurringCosts.taxAmount`
- `OrderPricingSummary.recurringCosts.total`
- `OrderPricingSummary.subtotal`
- `OrderPricingSummary.taxAmount`
- `OrderPricingSummary.total`
- `TaxBreakdownItem.amount`

Removed `netPrice`, `currencyOptions` and `balance`, the deprecated amounts in major currency units. Read `netPriceMinor`, `currencyOptionsMinor` and `balanceMinor` instead.

- `Price.currencyOptions`
- `Price.netPrice`
- `UsageVoiceIldPackage.balance`

Removed `Price.boundMonths`. Read `bindingContract.duration` instead, which carries the unit alongside the count.

- `Price.boundMonths`

Removed `POST /orders/{orderId}/calculate-price`. The order endpoints return the current price as `pricing`, and the platform calculates it again each time the order changes. The removed call only read back what `GET /orders/{orderId}` returns.

- `POST /orders/{orderId}/calculate-price`

This affects the following operations. An integration calling none of them can move to `2026-09-01.bullfinch` without changing anything.

- `GET /customers/{customerId}/product-catalog`
- `GET /invoices/{invoiceId}`
- `POST /invoices/{invoiceId}/mark-paid`
- `GET /licenses`
- `POST /licenses`
- `GET /licenses/{licenseId}`
- `POST /licenses/{licenseId}/cancel`
- `PUT /licenses/{licenseId}/product-offering-change`
- `GET /licenses/{licenseId}/product-offering-options`
- `GET /orders`
- `POST /orders`
- `GET /orders/{orderId}`
- `PUT /orders/{orderId}`
- `POST /orders/{orderId}/approve`
- `POST /orders/{orderId}/calculate-price`
- `POST /orders/{orderId}/cancel`
- `POST /orders/{orderId}/submit`
- `GET /product-offerings`
- `GET /product-offerings/{productOfferingId}`
- `GET /subscribers/{subscriberId}`
- `PUT /subscribers/{subscriberId}`
- `GET /subscriptions`
- `POST /subscriptions`
- `GET /subscriptions/usage`
- `GET /subscriptions/{subscriptionId}`
- `POST /subscriptions/{subscriptionId}/activate`
- `GET /subscriptions/{subscriptionId}/addon-options`
- `GET /subscriptions/{subscriptionId}/addons`
- `POST /subscriptions/{subscriptionId}/addons`
- `POST /subscriptions/{subscriptionId}/addons/cancel`
- `PUT /subscriptions/{subscriptionId}/addons/product-offering-change`
- `GET /subscriptions/{subscriptionId}/addons/product-offering-options`
- `POST /subscriptions/{subscriptionId}/block-sim`
- `POST /subscriptions/{subscriptionId}/cancel`
- `POST /subscriptions/{subscriptionId}/change-sim`
- `POST /subscriptions/{subscriptionId}/in-porting`
- `POST /subscriptions/{subscriptionId}/pause`
- `PUT /subscriptions/{subscriptionId}/product-offering-change`
- `GET /subscriptions/{subscriptionId}/product-offering-options`
- `POST /subscriptions/{subscriptionId}/restore`
- `POST /subscriptions/{subscriptionId}/suspend`
- `GET /subscriptions/{subscriptionId}/usage`

This affects the following webhook events. The webhook revision of your account decides which shape they carry, and it moves only when you move it.

- `license.activated`
- `license.cancelled`
- `license.created`
- `license.ended`
- `license.renewed`
- `license.updated`
- `order.cancelled`
- `order.created`
- `order.expired`
- `order.lineItemStatusChanged`
- `order.statusChanged`
- `order.submitted`
- `order.updated`
- `subscription.activated`
- `subscription.cancelled`
- `subscription.created`
- `subscription.ended`
- `subscription.first_activated`
- `subscription.paused`
- `subscription.portIn.completed`
- `subscription.portIn.created`
- `subscription.portIn.failed`
- `subscription.portIn.updated`
- `subscription.quotaNotification`
- `subscription.renewed`
- `subscription.restored`
- `subscription.subscriber_set`
- `subscription.suspended`
- `subscription.updated`
