# Stability and versioning

> What integrations can rely on, how the API changes and where to download the contract.

## Two version numbers

| Version          | Where                                              | Changes when                                            |
| ---------------- | -------------------------------------------------- | ------------------------------------------------------- |
| Path version     | `/api/v1` in every URL                             | An incompatible change to published operations is made. |
| Contract version | `info.version` in the contract, currently `0.10.0` | The contract changes in any way.                        |

The [changelog](https://passport.kabin.sh/docs/en/changelog) lists each contract version with its changes.

## What you can rely on

The published contract (ADR-020) contains exactly the operations integrations may use: the operations that
accept an API key and the public passport reads (tag `public`). Everything in it is the API this
documentation describes and the [API reference](https://passport.kabin.sh/docs/en/api-reference) lists.

The BatteryPass portal uses further, internal operations: sign-in, members, API key management, review,
publishing, imports. They are not in the published contract, need a portal session and may change in any
release without notice. Do not build on them.

## Compatible changes

These changes can come in any release without a new path version:

- new operations;
- new optional query parameters and new optional properties in request bodies;
- new properties in responses;
- new enum values, for example a new passport status or lifecycle event type;
- new problem codes and field error codes;
- a new version of the field registry with new fields, labels or requirements (read it with
  [`getRegistryInfo`](https://passport.kabin.sh/docs/en/api-reference/registry/get-registry-info)).

Write your client so that these do not break it:

- ignore response properties you do not know;
- handle unknown enum values with a sensible default instead of failing;
- treat an unknown problem `code` by its HTTP status;
- do not validate responses strictly against an older copy of the contract.

## Incompatible changes

Removing or renaming an operation, parameter or property, changing a type or meaning, or making optional
input required is incompatible. Such changes to published operations come only with a new path version and
are announced in the [changelog](https://passport.kabin.sh/docs/en/changelog).

## Download the contract

The contract is an OpenAPI 3.0 document, as JSON and YAML, without authentication:

| Address                                                                                                                                      | Content                                                           |
| -------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `$BATTERYPASS_URL/api/v1/openapi.json`, `$BATTERYPASS_URL/api/v1/openapi.yaml`                                                               | The contract of the BatteryPass deployment your organisation uses |
| [`/docs/openapi.json`](https://passport.kabin.sh/docs/openapi.json), [`/docs/openapi.yaml`](https://passport.kabin.sh/docs/openapi.yaml) | The contract this documentation describes                         |

For your integration, the contract of your deployment is authoritative: it matches the version that answers
your requests and can be older or newer than the one on this site. Check its version before you generate a
client:

```bash title="cURL"
curl -sS "$BATTERYPASS_URL/api/v1/openapi.json" | jq -r '.info.version'
```

> [!TIP]
> Generate typed clients from the contract and keep the `info.version` you generated from. Comparing it with
> the deployed version in your monitoring tells you when to read the changelog.
