Core Concepts
A few concepts govern how the entire API behaves. Once you understand them, every endpoint is predictable.
Operations
A capability is a single operation with a stable, dotted identifier
(orders.archive.place, items.create, catalog.search). An operation declares:
- a typed input model and a typed output model,
- a required scope (the one permission it needs),
- a side-effect classification (below),
- and, for producers, the kind of artifact it produces (an item, an order, a job…).
There are no REST verbs and no query parameters for operations. The verb (list, get,
create, delete) lives in the operation name, not in HTTP. Over HTTP an operation is
addressable two equivalent ways with identical body, auth, scopes, and errors — the
canonical operation-id endpoint POST /v1/op/{operation_id} (for example POST /v1/op/orders.archive.place) and a resource path POST /v1/{resource}/{action} (for example POST /v1/orders/archive/place). Both are published in the OpenAPI
document. The CLI and SDKs expose the same dotted namespace as commands and methods — orders.archive.place becomes geopera orders archive place, client.orders.archive.place(...) in Python, and client.orders.archive.place(...) in
TypeScript. See Operations for the full surface and Authentication for the Authorization: Bearer token.
The invoke pipeline
Every operation runs through the same fixed pipeline on every call, in this fixed order:
- Authenticate — resolve the caller from the Bearer token.
- Authorize (scope) — check the caller holds the operation’s required scope.
- Validate input — parse and validate the JSON body against the typed input model.
- Domain checks — enforce business invariants (existence, state, ownership).
- Open provenance — writes only; begin a lineage record before any state change.
- Execute — run the operation.
- Validate output — validate the result against the typed output model.
- Seal provenance — writes only; finalize the lineage record for what was produced.
- Audit — record the call.
No operation can opt out of any stage. That uniformity is the point: every call is
authenticated, scoped, and validated, and every write is recorded. Two stages run only
on writes — provenance is opened before and sealed after Execute for any non-read operation, and skipped entirely for reads.
Every operation is exposed over HTTP at its canonical POST /v1/op/{operation_id} route
and at the equivalent POST /v1/{resource}/{action} resource path; both share one
implementation, so the OpenAPI schema, the routes, and the implementation always stay in
sync.
Side-effect tiers
Every operation is honestly classified by what it does. The classification is part of
the API contract (surfaced as x-side-effect in the OpenAPI document) and drives
client-side safety hints:
| Tier | Meaning | Examples |
|---|---|---|
read | No state change | catalog.search, items.get, orders.archive.estimate |
compute | Changes state, no money | items.create, collections.update, uploads.complete |
external_spend | Spends credits / charges a card | orders.archive.place, processing.create, billing.topup |
share_export | Data leaves the platform | share.link.create, asset download, api_keys.create |
destructive | Deletes / tears down | items.delete, projects.archive, api_keys.revoke |
Reads are cheap and never touch the spend, approval, or provenance machinery. Writes
do. AI agents and SDKs use these tiers to mark operations as read-only or destructive —
the MCP tools derive their readOnlyHint and destructiveHint directly from the tier.
Response shapes
Most operations return a single typed JSON output model — the validated result of the call. Two variants exist:
- Raw-response operations. A few operations return their result directly rather than
wrapping it in the standard output model — for example, an operation that issues a
signed URL or returns a binary artifact. These still run the full pipeline; a
raw-response operation that returns a
4xx/5xxstatus is treated as “declined” and does not seal provenance. - Streaming / paginated reads. List-style reads do not stream unbounded results; they
return a page of results plus an opaque
cursor. Pass the cursor back in the next request body to fetch the following page; a null or absent cursor means you have reached the end. Cursors are stable across the lifetime of a result set and opaque — never construct or parse one on the client.
Idempotency
Operations that move money or create durable resources accept an Idempotency-Key header. Replaying a request with the same key returns the original result instead of
performing the action twice — safe to retry on a dropped connection. This is enforced
on the spend paths (placing an order, topping up credits, creating a processing job). See Idempotency for the full key contract and retry semantics.
Provenance
Geopera records lineage at write time. When an operation produces data — an order, a delivered item, a processing job’s outputs — it emits a provenance record linking the output to what produced it and what it was derived from, in the same transaction that created the data. Two consequences:
- It cannot be skipped. The platform refuses to return a producing operation as a success unless its output’s lineage was recorded. Provenance is a property of the write path, not an afterthought.
- It is walkable. “How was this produced?” is a query: an order traces to the product and captures it was placed for; a delivered item traces to its order; a processing output traces to the job and the inputs it ran on. Lineage survives even if a source is later archived.
This is the backbone for auditability and reproducibility — every artifact carries the record of how it came to exist.
One surface, every client
The same set of operations is available through every client, with consistent typing, scopes, and provenance:
- REST / OpenAPI — every operation is reachable two equivalent ways, the canonical
POST /v1/op/{operation_id}endpoint and thePOST /v1/{resource}/{action}resource path, both described by a published OpenAPI document. - CLI (
geopera) — each operation is a command mirroring its id, soorders.archive.placebecomesgeopera orders archive place. - Python SDK (
geopera) and TypeScript SDK (@geopera/sdk) — fully typed clients that expose the same namespace as methods, for exampleclient.orders.archive.place(...). - MCP (agent) tools — operations are also exposed as a Model Context Protocol tool catalog, so an AI agent can call them as tools, with read-only and destructive hints derived from the side-effect tier.
Every operation behaves identically across all of these surfaces — the same input and output models, the same required scope, and the same provenance.
Geospatial correctness
Geometry is GeoJSON in WGS84 (EPSG:4326) at the API boundary, and all rendering, re-projection, clipping, statistics, and band math are computed by the platform — the client sends parameters, the platform produces the correct result. This keeps every client (the portal, the SDKs, an agent) consistent: there is one authoritative place the computation happens.
Next steps
- Operations — browse the full operation surface.
- Authentication — get a token and the scopes each operation needs.
- Idempotency — the key contract and retry semantics.