Versioning
@geopera/sdk follows Semantic Versioning, and its package version is deliberately independent of the API version carried in the /v1 path prefix — the two move on their own schedules, and you should never assume they match.
Two version numbers, two meanings
When you depend on @geopera/sdk there are two distinct version numbers in play. Conflating them is the most common source of confusion, so it is worth fixing them in your mind up front.
| Number | Where it lives | Current value | What it describes | Cadence |
|---|---|---|---|---|
| Package version | package.json version | 2.1.0 | A release of the npm client | SemVer, moves often |
| API surface version | URL path prefix | /v1 | The calling convention for every operation | Changes only on a surface break |
The package version describes a client release. It moves whenever the npm package changes — a runtime fix, a new typed operation flowing in from an updated contract, a typing correction, a dependency bump. You select it with npm (@geopera/[email protected], @geopera/sdk@^2.1.0, @geopera/sdk@latest).
The API surface version lives in the path prefix. Every operation is invoked as POST /v1/op/{operation_id} against https://api.geopera.com (overridable via the baseUrl client option). The SDK targets /v1; it does not pin or send a separate spec version in a header, query string, or body field — /v1 is structural, baked into the URL of every request. See Concepts and Operations.
These two numbers are decoupled on purpose. The /v1 segment is a coarse, long-lived contract marker; the package number moves much faster, advancing through many patch and minor releases while /v1 stays put, because nearly all contract changes are additive and do not break the calling convention. For the full cross-client picture — including the Python client and the CLI — see the API-wide Versioning page.
How the package uses SemVer
The package follows Semantic Versioning: MAJOR.MINOR.PATCH.
- PATCH (
2.1.x) — backward-compatible fixes with no surface change: build fixes, typing corrections, dependency bumps, runtime bug fixes. Safe to take automatically. - MINOR (
2.x.0) — backward-compatible additions, typically new typed operations or new optional fields flowing in from an updated API contract. Existing code keeps compiling and running unchanged; the new surface is simply available. - MAJOR (
x.0.0) — a breaking change to the package’s own public API: a renamed namespace or method, a changed input/output type, a dropped export, or adoption of a breaking contract change. Read the changelog and re-run your typecheck before upgrading.
Because operation inputs and outputs are fully typed, an upgrade that changes an operation’s body or response shows up at compile time. Run tsc --noEmit after upgrading and every affected call site surfaces immediately as a type error rather than failing at runtime:
npm install @geopera/sdk@latest
npx tsc --noEmitThis is the single most useful property of the typed client during an upgrade: the type checker is your migration checklist.
What “breaking” means for the package version
A package MAJOR bump signals a change to the client surface you write against. Concretely, any of these triggers a major release:
- A namespace or method is renamed or removed (for example
client.catalog.searchmoving or changing shape). - A typed input or output model gains a required field, drops a field, or changes a field’s type in a backward-incompatible way.
- A top-level export is renamed or removed (for example
GeoperaClient,GeoperaError,callOperation,DEFAULT_BASE_URL, or an exported type such asGeoperaClientOptionsorOperationId). - The client adopts a breaking change in the underlying API contract.
Additive changes — a new operation, a new optional input field, a new field on a response, a new enum value — are minor, not major. They cannot break code that compiled against the previous version, so they never force a major bump.
What “breaking” means for the /v1 surface
The /v1 segment is the most stable thing in the API. It changes only for a surface-incompatible break — a change to the calling convention shared by all operations, such as the request method or path shape (moving away from POST /v1/op/{id}), the authentication model (see Authentication), the error envelope (see Errors), or the shared pagination or idempotency contract (see Pagination and Idempotency).
If such a break ever ships, it arrives at a new prefix (/v2/op/...) and /v1 continues to serve existing clients in parallel. You will never have an existing /v1 request silently change shape underneath you. A future /v2 surface would ship as a new major of @geopera/sdk that targets the new prefix; until then, every release of the package keeps speaking /v1.
The two breaking definitions are independent. A package major can ship without any /v1 change (for example, renaming a method for ergonomics). And a /v1 → /v2 surface break would necessarily come with a package major, but the reverse does not hold.
Installing and upgrading
Always install the published package from npm. The package is @geopera/sdk; it is ESM-first with a CommonJS fallback and requires Node 18 or newer.
npm install @geopera/sdk
# or: pnpm add @geopera/sdk
# or: yarn add @geopera/sdkUpgrade to the latest release and re-run your typecheck:
npm install @geopera/sdk@latest
npx tsc --noEmitPin an exact version when you want fully reproducible installs (your lockfile already does this; an exact spec in package.json makes it explicit):
npm install @geopera/[email protected]Choosing a version range
Pin the package the way you pin any dependency: allow minors and patches, cap the major, and upgrade across a major deliberately after reading the changelog.
# Allow 2.1.0 up to (but not including) 3.0.0 — recommended
npm install @geopera/sdk@^2.1.0The caret range ^2.1.0 resolves to the newest 2.x.y and refuses 3.0.0, so you automatically receive new operations and fixes while staying behind any breaking major. If you need tighter control during a freeze, a tilde range pins to patch level:
# Allow only 2.1.x patches
npm install @geopera/sdk@~2.1.0Expressed directly in package.json:
{
"dependencies": {
"@geopera/sdk": "^2.1.0"
}
}Reading the version at runtime
The version you actually resolved is recorded in your lockfile and queryable from the toolchain. Use these rather than hard-coding a number in your application:
# The version installed in this project
npm ls @geopera/sdk
# The latest version published to npm
npm view @geopera/sdk version
# Every published version, to see the release history
npm view @geopera/sdk versionsIf you need the version inside a Node program (for example to include it in a support log), read it from the package’s own manifest rather than maintaining a separate constant:
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const { version } = require('@geopera/sdk/package.json');
console.log(`@geopera/sdk ${version}`); // -> @geopera/sdk 2.1.0Worked example: a new operation flows through
Suppose the API gains a new operation. Here is how each version number responds, so you can see why the package version moves but /v1 does not.
/v1surface — unchanged. The new operation is invoked atPOST /v1/op/...exactly like every existing one. Adding an operation is additive.@geopera/sdk— released as a minor bump (for example2.1.0 → 2.2.0). The new operation appears as a typed namespace method; existing code is untouched.- Your code — keeps compiling and running. To use the new operation you bump the dependency within your
^2.xrange; you never changebaseUrlor the path prefix.
import { GeoperaClient } from '@geopera/sdk';
const client = new GeoperaClient({ token: 'gpra_...' });
// Existing call — identical before and after the upgrade.
const results = await client.catalog.search({
collections: ['sentinel-2-l2a'],
limit: 10
});The escape hatch behaves the same way across versions. client.invoke("catalog.search", body) dispatches to POST /v1/op/catalog.search regardless of which 2.x package you are on; a new operation just becomes a new valid OperationId literal once you upgrade.
Changelog
Release notes for each version are published with the package and in the source repository. Check the changelog before any major upgrade to see which namespaces, methods, or types changed.
- Release notes and tags:
geo-pera/geopera-typescripton GitHub. - Published versions and metadata:
@geopera/sdkon npm.
Watch the package changelog rather than the API’s spec version — the changelog is where breaking-vs-additive is called out for this client specifically. For the relationship between this package, the geopera Python client, the CLI, and the /v1 surface, see the API-wide Versioning page.
Guidance
- Build against
/v1and treat it as permanent for the life of your integration; a successor surface would ship at a new prefix and a new package major, never replace/v1in place. - Pin with
^2.1.0(minors and patches allowed, major capped), commit your lockfile, and upgrade across a major deliberately. - Run
tsc --noEmitafter every upgrade — the typed client turns contract changes into compile errors at your call sites. - Keep the two numbers separate in your head: the package SemVer (
2.1.0) and the API surface (/v1) move independently.
See Operations and the TypeScript quickstart for usage, and Client reference for the exported surface that SemVer protects.