<!-- Source: https://docs.geopera.com/api-reference/concepts · Markdown for LLMs -->

# Core Concepts

A handful of ideas explain how the whole API behaves. Understand these and every
endpoint becomes 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…).

Every operation runs through the same fixed pipeline on every call:

```
Authenticate → Authorize (scope) → Validate input → Domain checks
  → [open provenance] → Execute → Validate output → [seal provenance] → Audit
```

You cannot opt an operation out of any stage. That is what makes the API's guarantees
uniform: a capability cannot be added that skips authentication, scope, validation, or
provenance.

## 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.

## 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).

## 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 registry, every client

There is a single registry of operations, and every client is a **projection** of it,
generated from the same source:

- **REST / OpenAPI** — one typed route per operation; the OpenAPI document is reflected
  from the registry, so it never drifts from the implementation.
- **Python SDK** and **TypeScript SDK** — generated from that OpenAPI document, fully
  typed, no hand-maintenance.
- **MCP (agent) tools** — the registry projects into a Model Context Protocol tool
  catalog, so an AI agent can call operations as tools, with read-only and destructive
  hints derived from the side-effect tier.

Because all of these come from one source, adding an operation makes it available to
the REST API, both SDKs, and the agent surface at once — with the same typing, the same
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 backend — 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.
