Skip to main content

API versioning and deprecation policy

Breaking API changes ship only on a new /api version, and a deprecated operation answers with Deprecation and Sunset headers for at least 90 days.

The policy

An integration built against a released Platform API version keeps working when you upgrade the platform. From DALP 3.2, DALP does not remove an operation from a released version, or change one incompatibly, inside that version. A breaking change ships only on a new version, such as /api/v3, next to the version you already call. An operation or a whole version is removed only after a deprecation announcement that gives at least 90 days' notice. /api/v2 became a released version in DALP 3.2, so the v2 changes that 3.2 made fall outside this policy. DALP 3.2 also changed v1 without that notice: it removed three operations, the wallet field of v1 user reads, the gasPrice and gasUsed fields of v1 user events and the defined field of error bodies, as Upgrade an integration to DALP 3.2 lists.

Each version path is a separate contract:

Version
Status
Contract rule
/api/v1
Stable since DALP 3.0
Structure frozen: paths, methods, inputs and success responses, apart from the DALP 3.2 changes that Upgrade an integration to DALP 3.2 lists
/api/v2
Stable from DALP 3.2
The same rule as v1 from the 3.2 release

Before a version is released, it can still change between development builds, and every such change is listed in the release notes. From its first release onward, the rule on this page holds for as long as the version is served. Upgrade an integration to DALP 3.2 lists the v2 changes between DALP 3.1 and the 3.2 release.

What counts as a breaking change

A change is breaking when a client that worked against the previous release can fail against the new one without changing its own code. A released version does not take these changes:

  • Removing a path, or a method on a path.
  • Adding a required input: a path, query, or header parameter, or a request body field.
  • Removing or narrowing an accepted input, such as dropping an enum value or tightening a format.
  • Removing a field from a success response, or changing its type.

Before each release, DALP compares the paths, methods, inputs and success responses of version 1 with a sealed copy of its contract. For version 2, it compares the contract it publishes with the contract already served, and refuses a removed path or method, a removed parameter, an input that becomes required, and a removed response status. Either comparison lets a difference through only when the maintainers record it as an accepted change with its reason, which is how the DALP 3.2 changes to version 1 shipped. The version 2 comparison does not read the values an input accepts or the fields of a response, so those two rules depend on review.

These changes are not breaking, and ship inside a released version:

  • A new operation, or a new optional input on an existing one.
  • A new field in a success response. Ignore response fields your client does not know. A strict decoder that rejects unknown fields breaks on a change DALP treats as compatible.
  • A new error on an existing operation, for example a new rejection when a request conflicts with platform state. Handle errors by their class and the retryable flag, as Errors describes, so a new error code reaches a branch your client already has.
  • Changes to descriptions, examples, summaries, and operation tags in the OpenAPI document.

How a deprecation is announced

A deprecated operation keeps working until its sunset date, and tells you on every response that it is going away. DALP announces a deprecation in two places at the same time: on the wire, and in the OpenAPI contract.

On the wire, every response from a deprecated operation carries three headers. That includes error responses, such as a rate-limit refusal, so a client sees the notice whatever the request outcome.

Header
Standard
Value
Deprecation
RFC 9745
The date the deprecation was announced, as @ and Unix seconds: @1799971200
Sunset
RFC 8594
The first day the operation can stop answering, as an HTTP date: Thu, 15 Apr 2027 00:00:00 GMT
Link
RFC 8288
This policy as rel="deprecation", and each replacement path as rel="successor-version"

An illustrative full set of headers on one response:

Deprecation: @1799971200
Sunset: Thu, 15 Apr 2027 00:00:00 GMT
Link: <https://docs.settlemint.com/docs/api-reference/guides/versioning-and-deprecation>; rel="deprecation"; type="text/html", </api/v2/example-operation-next>; rel="successor-version"

Sunset is omitted while no sunset date is set. The API exposes all three headers to browser clients through cross-origin resource sharing (CORS), so a web application can read them as well as a server integration.

In the OpenAPI contract, the operation carries deprecated: true, documents the same headers on its success responses (Sunset only when a sunset date is set), and holds the announcement in the x-dalp-deprecation extension:

{
  "deprecated": true,
  "x-dalp-deprecation": {
    "deprecatedAt": "2027-01-15",
    "sunsetAt": "2027-04-15",
    "successors": ["/api/v2/example-operation-next"]
  }
}

Check how the client generator you use treats deprecated: true. The contract flag, the announcement and the headers come from one declaration, so they never disagree.

The notice window

The sunset date is at least 90 days after the deprecation date. DALP refuses a deprecation declared with a sunset date less than 90 days after its announcement date, so no release can announce a shorter window. The rule covers a declared deprecation: the DALP 3.2 changes to version 1 shipped without one.

The lifecycle of a deprecated API operationA current operation is deprecated on an announced date. From then on every response carries the Deprecation, Sunset, and Link headers, and the contract marks it deprecated. At least 90 days later, on the sunset date, a release can remove it. A breaking replacement ships on a new API version.Operation lifecycleCurrentChanges stay compatibleHeaders on every answerDeprecatedDeprecation, Sunset, LinkAt least 90 daysSunsetA release can remove itReplacement lives on its successor path

An operation moves from current to deprecated on the announcement date, and cannot be removed until its sunset date, at least 90 days later.

The 90-day window is a minimum. DALP can keep a deprecated operation past its sunset date, and a later release can move the sunset further out. It never moves it closer than 90 days after the announcement.

The same window applies to a whole version. When a version is deprecated, every operation it serves answers with the headers. Routes under /api/auth, which each version's OpenAPI document also lists, do not carry them. The version path is removed only after its own sunset date.

Find deprecated operations

The OpenAPI document of a version marks every deprecated operation of that version deprecated: true. The /api/auth routes it also lists are not marked, even when the version is deprecated, so the command omits them. This command prints one line per deprecated operation, with its sunset date and replacement paths. The request is illustrative: replace the host with your deployment.

curl -s "https://your-instance.example.com/api/v2/spec.json" | jq -r '
  .paths | to_entries[] | .key as $path | .value | to_entries[]
  | select(.value | type == "object" and .deprecated == true)
  | "\(.key | ascii_upcase) \($path) sunset \(.value["x-dalp-deprecation"].sunsetAt // "none") successors \((.value["x-dalp-deprecation"].successors // []) | join(","))"'

For example, with an illustrative operation:

GET /api/v2/example-operation sunset 2027-04-15 successors /api/v2/example-operation-next

The command prints nothing when the version has no deprecated operation. Run it with /api/v1/spec.json to check the first version too.

What your integration should do

Watch for the Deprecation header in the client you use against DALP, and treat it as a work item rather than an error. Log the method, path, and Sunset value once per operation, so the notice reaches a person before the sunset date.

When you see the headers:

  1. Read the successor-version links for the replacement path.
  2. Check the release notes for the release that announced the deprecation. Its compatibility section names the operation and the change.
  3. Move your calls to the successor before the sunset date, and test against a DALP build that still serves both.

After the sunset date, a release can remove the operation. A call to a removed path fails as a route that does not exist.

How releases record API changes

Every release entry has a compatibility section, which DALP 3.0 calls Breaking changes and migration. It names each deprecation the release announces, with its sunset date and replacement, and each operation or version the release removes after its sunset. A new version is announced in the release that makes it stable. See the changelog for each release.

Next steps

  • Upgrade an integration to 3.2 for every v2 change 3.2 made that can break a 3.1 or 3.0 client, including the reads it widened and what a strict decoder needs.
  • Errors for the error class and retryable flag that keep a client working when an operation gains a new error.
  • V2 API reference and V1 API reference for each operation's contract, including its deprecation status.

Was this page helpful?