API Versioning

CycleCalcs publishes two API versions. /v1 is closed to new development and will not change again. /v2 is the current, actively developed contract, and the one to build against. This page states what "change" means for each, how a breaking change ships, and how to pin your integration to a specific published contract.

On this page

Where things stand

PathStatusWhat that means
/v1FrozenNo field is renamed, removed or retyped. No error code changes meaning. No cap tightens. Existing integrations keep working exactly as they do today, indefinitely.
/v2CurrentEvery new endpoint, field and fix lands here. This is the version to build against.

The API states this itself, as data rather than prose. GET /v2 reports:

"frozen_versions": [
  {
    "version": "1",
    "base": "https://www.cyclecalcs.com/v1",
    "status": "frozen",
    "note": "Version 1 is unchanged and will not change. New work happens on /v2."
  }
]

What counts as additive

These change /v2 at any time, without a version bump and without advance notice, because a client that ignores what it does not recognize is unaffected by them:

  • A new field appended to a response.
  • A new warning code appended to the warnings array.
  • A new endpoint added under /v2.

None of these renames or removes anything you already depend on. If your client reads known fields by name and does not choke on an extra JSON key or an unrecognized warning code, additive changes are invisible to you.

What counts as breaking

These never happen inside /v2. Each one ships as a new major version path instead:

  • Removing a field.
  • Renaming a field.
  • Changing a field's type, a number becoming a string, for instance.
  • Changing the error code returned for a condition that already has one.
  • Tightening a published cap: a lower rate limit, a smaller row cap, a shorter search window.

If a change like this is ever needed, it appears at /v3. /v2 keeps its present behavior for the rest of its life, the same way /v1 does today.

Pin your integration

Every /v2 response carries meta.contract_version, a semantic version. Right now, every response reports:

"meta": { "contract_version": "2.0.0", ... }

GET /v2 also echoes it as data.contract_version, describing the API as a whole, but meta.contract_version is the one to check: it is present on every single 2xx response from every endpoint, so you can read it off the exact answer you just received rather than making a separate call to the index.

The three numbers mean:

  • Patch (the third number) changes for a fix that does not alter behavior anything could depend on.
  • Minor (the second number) changes when an additive change, as defined above, ships.
  • Major (the first number) stays 2 for the entire life of this path. A change big enough to need a new major number ships at /v3, per the policy above; it is never applied to /v2 in place.

A caller that wants an early signal of an additive change can watch meta.contract_version across requests. A caller that only reads the fields it already knows about does not need to watch anything.

Deprecation

/v2 has not retired anything since launch. If an endpoint is ever retired, the response for that endpoint becomes 410 Gone with code ENDPOINT_RETIRED, and the hint on that response names the replacement endpoint directly, not a separate document you have to go find first.

/v2 does not send Deprecation or Sunset response headers. There is no header to poll for advance warning. A live endpoint tells you immediately, in its own response, if it has anything pending; this page is the other place to check.

Because breaking changes move to a new major version path rather than mutating /v2 in place, retiring an endpoint inside /v2 should be rare. Most future work is additive, and most callers will never see a 410 from this API.