<!-- Generated by `just docs` from docs/API-STABILITY.md. Edit the source, not this file. -->

# API stability

This page says which parts of atmon your code may depend on, what we promise
about them, and what we do before any of it changes. It is written for somebody
who has shipped against the API and needs to know whether next month's release
can break them.

## What the promise covers

The public API is `automaton.v1`, and it is exactly the surface documented in
the [API reference](./api/index.md):

| Surface | What your code does with it |
|---|---|
| Router | Describes a task and gets back a ranked slate of tools, then reports which one worked. |
| Catalog | Reads what exists: apps, their tools, one tool's full definition. |
| Execution | Runs one tool and reads the receipt it leaves. |
| Jobs | Hands over work bigger than one call, then reads it back and answers what it asks. |
| Connections | Connects an account on behalf of one of your users, reads its state, disconnects it. |
| Keys | Mints, lists, and retires the project's own API keys. |
| Triggers | Subscribes an address to an app's events, reads what arrived, replays a delivery. |
| Traces | Reads back one decision and everything that ran under it. |
| Usage | Reads what this project has used. |

The rule is one sentence: if a call is not in the API reference, it is not part
of this promise. The rest of the tree serves the console and our own
components, it changes when the console changes, and no notice is given for it.
That is not a hidden boundary. Every contract names its audience on its own
declaration, and a build check holds the set marked public equal to the set the
reference documents, so the two cannot drift apart without failing.

## The promise

**Changes are additive.** A field, a call, or a service can be added. An
existing one keeps its name, its number, its type, and its meaning. A client
generated against `automaton.v1` today keeps compiling and keeps returning the
same answers as the surface grows around it.

**A machine enforces it, not a habit.** Every change to the contracts runs a
compatibility check against the contracts already published. A change that
would break a generated client fails the build, so it cannot reach a release by
being missed in review.

**Error codes only grow.** The `error_code` on a receipt is a string you may
switch on. Codes are added; an existing code is never repurposed to mean
something else. Write your handling so an unfamiliar code falls through to the
same path as a failure you cannot classify, and it will keep working when the
list grows. The full list, and what to do about each code, is in
[Error codes](./errors.md).

**Nothing is removed without a replacement and a date.** A call or field we
intend to remove is first marked deprecated in the reference, with the call
that replaces it named and a sunset date given. The old shape keeps answering
until that date. There is no removal without both.

**A change we cannot make additively becomes a new version.** It would ship as
`automaton.v2` beside `automaton.v1`, not as an edit to `v1`.

## Where the beta changes this

atmon is in beta, and the honest statement of that is short: the promise above
starts now, and while the service is in beta a breaking change is possible.

If we have to make one, you get told before it ships, the replacement is named,
and the old shape keeps answering for a stated window. What we will not do is
claim the promise is absolute today and then revert it, because a promise that
gets withdrawn is worth less than one that was stated accurately in the first
place.

When the beta ends, this section is what changes. The rest of the page is
already the way we work.

## What the promise does not cover

**The catalog's contents.** Which apps and tools exist is data, and it moves as
those apps move: tools are added, descriptions are tuned, an app's own API
changes under us. The shape of the calls you make is covered here; the list of
what you can call through them is not. Resolve tools by describing the task
rather than by hard-coding a slug you read once.

**Operational settings.** Rate ceilings, page sizes, timeouts, and quotas are
tuned as the service is run. The current values are in
[Limits](./limits.md), and a call that meets one gets an error code from the
list above rather than a surprise.

**The console.** What a screen shows, where a setting lives, and what the
console's own calls look like are all free to change.

**Anything behind a flag we tell you is unreleased.** If a call is not in the
reference, it is not released, whatever a response happens to contain.
