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

# API Versioning

> How Loop versions its public API and what that means for your integration.

## Why versioning exists

Loop's API is used by merchants and third-party developers to build integrations. Without versioning, every change Loop makes could break existing code. With versioning, you pin your integration to a specific API version and it continues to behave exactly as you built it — regardless of changes made to newer versions.

## Version format

Loop uses a date-based version format: `YYYY-MM`.

Loop ships new versions on a regular, predictable release schedule, so the [version lifecycle](#version-lifecycle) windows below stay consistent and easy to plan around. Each version is named after the month it ships (`YYYY-MM`), and a new version is cut whenever there are meaningful breaking changes to release.

The version appears directly in the URL path:

```
https://api.loopreturns.com/api/2026-07/orders
```

<Note>
  Each new version is preceded by a **2-week code freeze**, during which no additional breaking changes are accepted into the release. This gives the team time to finalise documentation and notify developers before the version ships.
</Note>

<Note>
  The alias `v1` is a legacy convenience alias for version `2026-07`. It exists purely for backward compatibility — new integrations should specify `2026-07` (or a later version) explicitly rather than relying on `v1`. Once `2026-07` reaches the **Sunset** stage of its [lifecycle](#version-lifecycle), the `v1` alias will be phased out entirely and requests must use an explicit `YYYY-MM` version.
</Note>

## Specifying your version

Include the version in every request URL. For example:

```
GET https://api.loopreturns.com/api/2026-07/returns
```

<Warning>
  If you omit the version from the URL, the API defaults to the oldest currently supported version. This is **not recommended for production** integrations — always specify a version explicitly so your integration's behaviour is predictable.
</Warning>

## Version lifecycle

Each version moves through three stages:

| Stage          | Duration                   | What it means                                                                                                              |
| -------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Active**     | 0–12 months after release  | Fully supported. No action required.                                                                                       |
| **Deprecated** | 12–15 months after release | Still works, but responses include a `Sunset` header indicating the retirement date. Migrate at your earliest opportunity. |
| **Sunset**     | 15+ months after release   | Version is retired. Requests are automatically upgraded to the oldest currently supported version.                         |

<Info>
  **Lifecycle timing**: a version is deprecated 12 months after its release date and sunset 15 months after its release date.

  **Example**: a version released in a given month enters the **Deprecated** stage 12 months later, and is **Sunset** 3 months after that (15 months after release).
</Info>

When your version is deprecated, watch for the `Sunset` response header — it tells you the exact date your version will be retired so you can plan your migration.

## Breaking vs. non-breaking changes

Not all API changes require a new version. Loop distinguishes between breaking and non-breaking changes:

### Breaking changes — shipped in a new version

A change is **breaking** if existing code would stop working without the developer doing anything. The following are always breaking changes:

* Removing or renaming a field in a response
* Changing a field's data type
* Making a previously optional request parameter required
* Removing an endpoint
* Changing the structure of error responses
* Removing a value from an enum

### Non-breaking changes — shipped to all versions

The following are **non-breaking** and are added to all supported versions simultaneously:

* Adding new optional fields to responses
* Adding new optional request parameters
* Adding new endpoints
* Adding new webhook event types

<Tip>
  **The rule of thumb**: if your existing code would break without you touching it, it's a breaking change and will only appear in a new version.
</Tip>

## How backward compatibility works

Loop's API runs the latest internal logic on every request. When you use an older version, response transformation functions reshape the output to match the schema that version defined.

This means:

* You're always running on the most up-to-date infrastructure and business logic
* Bug fixes are applied across all supported versions automatically — you get improvements without needing to upgrade
* Your integration sees the world through the lens of the version you chose

## Unstable version

The `unstable` version is a preview of the next planned release:

```
GET https://api.loopreturns.com/api/unstable/returns
```

<Warning>
  **Do not use `unstable` in production.** The unstable version may change at any time without notice. It exists to let you explore upcoming changes and provide feedback before they are locked in.

  All responses from the unstable version include an `X-Loop-API-Warning` header to remind you that the version is not production-ready. Webhooks **cannot** be configured to use the unstable version.
</Warning>

## Webhooks

Webhooks use the same versioning system as the REST API. Your webhook version is set once at the shop level and applies to all webhook payloads your shop receives.

Webhook version is not configured through the API. Instead, set it on the **outgoing webhook configuration** page in the Loop admin portal, where you can select which API version your webhook payloads should be shaped by.

The same version lifecycle — Active, Deprecated, Sunset — applies to webhook versions. When a new API version introduces a breaking change, it can affect both REST API responses **and** webhook payloads. Plan migrations for both surfaces together.

<Note>
  Webhooks cannot be pinned to the `unstable` version.
</Note>

## Quick reference

| Topic                    | Detail                                                                                                    |
| ------------------------ | --------------------------------------------------------------------------------------------------------- |
| **Format**               | `YYYY-MM` (e.g. `2026-07`)                                                                                |
| **Cadence**              | Regular, predictable release schedule. Versions are named for their release month (`YYYY-MM`).            |
| **Freeze period**        | 2-week code freeze before each new version ships                                                          |
| **Where to set it**      | URL path: `/api/{version}/...`                                                                            |
| **Legacy alias**         | `v1` = `2026-07`; phased out once `2026-07` reaches Sunset — use an explicit `YYYY-MM` version after that |
| **Support window**       | 15 months from release date                                                                               |
| **Deprecated behaviour** | Requests still work; `Sunset` header added to responses                                                   |
| **Sunset behaviour**     | Requests upgraded to oldest supported version                                                             |
| **Breaking change rule** | If existing code breaks without a developer change, it's breaking                                         |
| **Non-breaking changes** | Shipped to all versions simultaneously                                                                    |
| **Bug fixes**            | Applied to all supported versions                                                                         |
| **Unstable version**     | `/api/unstable/` — preview only, not for production                                                       |
| **Webhook versioning**   | Set on the outgoing webhook configuration page in the Loop admin portal; same lifecycle applies           |
