> ## Documentation Index
> Fetch the complete documentation index at: https://docs.enfuce.com/llms.txt
> Use this file to discover all available pages before exploring further.

# API Versioning

> How Enfuce versions its APIs, which changes are compatible or breaking, and how to build an integration that handles compatible changes without code changes.

Enfuce versions its APIs per endpoint, in the URL path. We add backwards-compatible changes to the current version of an endpoint, and we release a new version of the endpoint when a change would break existing integrations.

## How Versioning Works

The version is part of the URL of every request, directly after the base path of the API:

```text theme={null}
https://{base_url}/card/v4/{id}
```

| Element | Example | Description |
| - | - | - |
| Host | `integration-api-cat2.live.ext.prod.cia.enfuce.com` | Depends on the API and the environment. Take it from the API reference of the endpoint you call. |
| API base path | `/card` | Identifies the API — for example `/card`, `/account`, `/customer` or `/pin`. |
| Version | `/v4` | The version of the endpoint. |
| Endpoint path | `/{id}` | The resource and operation within that version. |

Versions follow these rules:

* **Each endpoint has its own version.** There is no single version for the platform or for a whole API, and you select the version only through the URL path. One API can have current endpoints on different versions — for example, the Card API has multi-application card endpoints on `v1`, plastic endpoints on `v3` and card endpoints on `v4`. Use the version shown for each endpoint in the API reference.
* **Compatible changes stay in the current version.** We add them to the existing endpoint without changing its URL, and publish them in the [Release Notes](https://docs.enfuce.com/updates/release-notes.md).
* **Breaking changes get a new version.** We release the changed endpoint under a new version in the path, and mark the previous version as deprecated.

```mermaid theme={null}
flowchart TD
    A[Change to an endpoint] --> B{Backwards-compatible?}
    B -- Yes --> C[Added to the current version, same URL]
    B -- No --> D[Released under a new version in the URL path]
    D --> E[Previous version marked as deprecated]
    C --> F[Published in the Release Notes]
    E --> F
```

When an endpoint has a newer version, both versions appear in the API reference and the older one is labelled **(Deprecated)**:

| Operation | Current endpoint | Deprecated endpoint |
| - | - | - |
| Get card | `GET /card/v4/{id}` | `GET /card/v3/{id}` |
| Get accounts given customerId | `GET /account/v4/customer/{customerId}` | `GET /account/v3/customer/{customerId}` |
| View PIN | `POST /pin/v3/view` | `POST /pin/v2/view` |

> [!NOTE]
>
> Don't build new integrations on deprecated endpoints. If you already use one, plan your move to the current version — for example, from `GET /card/v3/{id}` to the [Get Card Endpoint](https://docs.enfuce.com/payment/api/get-card/get-card.md).

The [Authorisation Control](https://docs.enfuce.com/payment/api/authorisation-control.md) and [Authorisation Forwarding](https://docs.enfuce.com/payment/api/authorisation-forwarding.md) webhooks are requests that Enfuce sends to an endpoint you host, so their paths are not versioned. The compatibility rules on this page apply to their payloads in the same way as to API responses.

## Compatible and Breaking Changes

Whether a change gets a new version depends on whether an integration built to the current API reference keeps working after it.

### Compatible Changes

We consider the following changes backwards-compatible. We make them in the current version of an endpoint, and your integration must handle them without code changes:

* Adding new APIs or endpoints.
* Adding new optional parameters to existing requests.
* Adding new attributes to existing responses and webhook payloads.
* Adding new values to existing enums, in responses, webhook payloads and requests.
* Changing the order of attributes in responses and webhook payloads.
* Changing human-readable text, such as the `message` attribute of error responses.

For example, we added the `merchantZipCode` attribute to `merchantData` in the Authorisation Control webhook without a new version. Integrations that ignore unknown attributes kept working unchanged.

> [!NOTE]
>
> An enum in the API reference lists the values that exist today, not every value the parameter or attribute can ever hold. We can add a value to an existing enum at any time — for example, a new card `status` — so handle values you don't recognise as described in [Integration Recommendations](#integration-recommendations).

### Breaking Changes

We consider the following changes breaking, and release them only in a new version of the endpoint:

* Removing or renaming an endpoint, parameter or attribute.
* Changing the data type or format of an existing parameter or attribute — for example, from a string to an object.
* Adding a new required parameter, or making an optional parameter required.
* Removing an enum value, or changing the meaning of an existing value.
* Changing the HTTP method or path of an endpoint.
* Changing the HTTP status code returned for an existing outcome.
* Adding validation that rejects requests that were previously valid.
* Changing the behaviour applied when an optional parameter is omitted.

### Integration Recommendations

Compatible changes reach your integration in the version you already call, without a change to the URL. To handle them without code changes, build your integration to accept data it doesn't recognise:

* **Ignore unknown attributes.** Configure your JSON parser to skip attributes your data model doesn't define, rather than fail. Some libraries fail by default — for example, Jackson in Java throws an exception unless you disable `FAIL_ON_UNKNOWN_PROPERTIES`.
* **Handle unknown enum values.** Map a value you don't recognise to a fallback, such as `UNKNOWN`, instead of failing the whole response. Decide what the safe behaviour is for an unknown value — for example, don't treat a card with an unrecognised `status` as usable. Log the value so you can check the Release Notes and update your mapping. Avoid exhaustive `switch` statements without a default branch.
* **Validate leniently.** If you validate responses or webhook payloads against the OpenAPI specification, allow additional attributes and additional enum values.
* **Read attributes by name.** Don't depend on the order of attributes in a JSON object.
* **Expect optional attributes to be missing or `null`.** For example, `merchantZipCode` is `null` when the card Scheme doesn't provide it.
* **Use error codes, not error messages.** Base your error handling on the HTTP status code and the `errorCode` and `errorType` attributes of the error response. The `message` attribute is for people and can change.
* **Treat identifiers as opaque.** Store identifiers such as `cardId` and `customerId` exactly as returned, and don't derive meaning from their structure.
* **Follow the Release Notes.** Subscribe to the RSS feed of the [Release Notes](https://docs.enfuce.com/updates/release-notes.md) to learn about new attributes, values and versions, and to plan your move away from deprecated endpoints.

For example, with Jackson in Java you can ignore unknown attributes and map unknown enum values to a default:

```java theme={null}
ObjectMapper mapper = new ObjectMapper()
    .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
    .configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE, true);

enum CardStatus {
    CARD_OK,
    CARD_BLOCKED,
    SUSPECTED_FRAUD,
    CARD_CLOSED_DUE_TO_FRAUD,
    CARD_NO_RENEWAL,
    CARD_LOST,
    CARD_STOLEN,
    CARD_CLOSED,
    @JsonEnumDefaultValue
    UNKNOWN
}
```

> [!WARNING]
>
> Apply the same rules to your webhook endpoints. If your Authorisation Control or Authorisation Forwarding endpoint rejects a payload because it contains an attribute or value it doesn't recognise, it can't return a decision for that authorisation.
