---
title: "Agentic Atlas API reference · Agentic Atlas"
description: "Every read-only JSON operation in the Agentic Atlas API, with its parameters, bounds and refusals. No key, no account, no JavaScript needed to read it."
canonical: "https://agentic-atlas.dev/api-reference"
last-updated: "2026-08-19"
---

For developers and agents

# Agentic Atlas API reference

Read-only JSON access to the Agentic Atlas: field-tested patterns for designing agentic systems — skills, subagents, plugins, and multi-agent workflows.

## What this page is

Every operation below is read out of this deployment's own [OpenAPI description](https://agentic-atlas.dev/openapi.json), which is the authoritative document — the same one [the browsable reference](https://agentic-atlas.dev/docs) fetches and builds in your browser. This page is the version that needs no JavaScript, so an indexer, an answer engine, or a `curl` can read the whole API without running anything.

The description is currently serving Release `v1.0.2`. Prefer [the machine-readable document](https://agentic-atlas.dev/openapi.json) if you are generating a client: it carries the response schemas, the declared headers and the retirement policy that this page summarises.

## How to call the Agentic Atlas API

Every operation is a `GET` under `/api/`, and there are no others: nothing here creates, updates, or deletes, and no call has a side effect. There is [no authentication](https://agentic-atlas.dev/auth.md) — no key to obtain, no quota to register for, and no account. Reads are limited per address, and every response states the window rather than making you discover it by hitting it.

Each response names the Release it was served from in `X-Catalog-Revision`, so a caller can always tell whether two answers describe the same Atlas. Breaking changes increment `API-Version`; additive ones do not, so parse leniently.

If you are wiring up an agent rather than an application, the [hosted MCP endpoint](https://agentic-atlas.dev/mcp/) is the better surface, and [the connect page](https://agentic-atlas.dev/connect) holds a worked first call. The [agent manifest](https://agentic-atlas.dev/llms.txt) names every machine-readable surface this domain publishes.

## Example requests

These run as written — no key, no header, no account, and nothing to install. They are the surface used in the order it was built to be used: arrive with the problem you have, not with an id you would have had to already know.

```
# 1. Turn a design problem into candidate identities.
curl -s 'https://agentic-atlas.dev/api/orient?cue=my+agent+keeps+running+out+of+context'

# 2. Read the Card for each id step 1 handed back — one call, not one per id.
curl -s 'https://agentic-atlas.dev/api/cards?ids=FIRST_ID&ids=SECOND_ID'

# 3. Read one whole Node, when its Card is not enough.
curl -s 'https://agentic-atlas.dev/api/nodes/FIRST_ID'
```

Two shortcuts onto that path. If you hold a title rather than a problem, `/api/resolve?name=A+NODE+TITLE` maps it onto the canonical id the other operations accept; if you already know a word of what you need, `/api/search?q=verification` goes straight to the plates that carry it. And `/api/tree` is the whole published index in canonical order, which is where a crawl should start.

A refusal is JSON on this surface too, shaped `{"error": {...}}`, so a caller reads what went wrong rather than inferring it from the status alone. The one exception is a malformed parameter, which the framework rejects before the operation is reached and answers with a `detail` array instead of an `error` object; the OpenAPI description says which statuses can carry which shape.

## Operations

14 operations, in the order the publisher recommends reading them.

### `GET /api/orient`

**Turn a design cue into candidate identities** Operation id `orient`.

Resolves ordinary design vocabulary — a phrase like *my agent keeps running out of context* — into candidate canonical identities, each with its status and hook. The entry point for a caller that does not yet know what to ask for. A miss is a successful, empty payload rather than an error, so an unknown cue needs no special handling.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `cue` | query | string | no | One routing cue key. Omit it to read every published cue with its candidates, which is the usual first call. |
| `limit` | query | integer; default 3; 1 to 8 | no | How many candidate identities to carry per cue. A bound, not a page: there is no offset to advance and the ordering is the publisher's, so a smaller bound returns a prefix of the same list. |

Answers: `200` The requested reading of the active Release.; `404` No such subject in the active Release.; `422` A parameter value is outside its permitted range, or could not be parsed into its declared type. The two carry different bodies — see the schema.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/tour`

**Read the publisher-curated first tour** Operation id `readTour`.

The ordered walk the publisher recommends for a first reading, with the narration explaining why each step follows the last. A Release that seals no tour answers with an absent walk rather than refusing.

Takes no parameters.

Answers: `200` The requested reading of the active Release.; `404` No such subject in the active Release.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/cards`

**Read the Card for each of several canonical ids** Operation id `readCards`.

Batch-reads Cards — hook, status, the publisher's decision-bearing claims, and compact source addresses — for ids you already hold. The batch is atomic: one unadmitted id fails the whole request and returns no cards, so drop the offending id and re-batch rather than falling back to one call per id. Only the first `limit` ids are read, and the surplus is dropped without a refusal or a truncation flag, so send no more ids than `limit`.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `ids` | query | string, repeatable | no | Canonical ids to read, repeated: `?ids=a&ids=b`. This is the batch read — prefer it to one call per id. Send no more than `limit` ids: the surplus is dropped silently and the response reports no truncation. |
| `limit` | query | integer; default 3; 1 to 8 | no | How many of the supplied ids are read. Ids past this position are dropped rather than refused. |

Answers: `200` The requested reading of the active Release.; `404` No such subject in the active Release.; `422` A parameter value is outside its permitted range, or could not be parsed into its declared type. The two carry different bodies — see the schema.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/search`

**Full-text search across the active Release** Operation id `search`.

Plain full-text search over every published plate, optionally narrowed by kind and status. Each hit carries the evidence that matched, so a caller can judge relevance without reading the whole Node. Use this when you already know a word of what you need; use orient when you do not.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `q` | query | string | no | The search terms, read as PostgreSQL reads them: every term must match, and a leading `!` excludes. An empty query is accepted and matches nothing. |
| `kind` | query | string; one of: concept, example, pattern | no | Narrow to one kind of published record. Any other value is refused with 400 rather than ignored. |
| `status` | query | string; one of: drafting, fleshed, needs-work, seeded, stable | no | Narrow to one rung of the status ladder. Any other value is refused with 400 rather than ignored. |
| `limit` | query | integer; default 10; 1 to 25 | no | How many hits to carry. A bound, not a page: the ranking is stable within one Release, so this returns the top `limit` and there is no second page behind it. |

Answers: `200` The requested reading of the active Release.; `400` The query is not one this Catalog can read.; `422` A parameter value is outside its permitted range, or could not be parsed into its declared type. The two carry different bodies — see the schema.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/compare`

**Compare several Nodes section by section** Operation id `compare`.

Aligns two or more Nodes on their shared sections so the differences between neighbouring patterns can be read directly. Nodes whose disclosure levels differ are not comparable and are refused rather than aligned misleadingly.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `ids` | query | string, repeatable | no | The canonical ids to align, repeated: at least 2 and at most 4. A selection outside that range, or one mixing disclosure levels, is refused with 422 rather than aligned misleadingly. |
| `sections` | query | string; default decision; one of: all, decision | no | Which sections to align: `decision` for the decision-bearing ones, `all` for every shared section. |

Answers: `200` The requested reading of the active Release.; `404` No such subject in the active Release.; `422` A parameter value is outside its permitted range, or could not be parsed into its declared type. The two carry different bodies — see the schema.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/tree`

**Walk the canonical ordered traversal** Operation id `readTree`.

Every published Node in the canonical order the survey defines, never re-ranked by relevance, with each Node's place in the hierarchy. This is the machine-readable index of the whole Release and the right starting point for a crawl.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `kind` | query | string; one of: concept, example, pattern | no | Narrow the traversal to one kind. Any other value is refused with 400. |
| `status` | query | string; one of: drafting, fleshed, needs-work, seeded, stable | no | Narrow the traversal to one rung of the status ladder. Any other value is refused with 400. |

Answers: `200` The requested reading of the active Release.; `400` The query is not one this Catalog can read.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/resolve`

**Resolve a name to a canonical id** Operation id `resolveName`.

Maps a title, alias, or near-miss spelling onto the canonical id that addresses it. Canonical ids are not guessable, so this is how a caller holding only a human-readable name reaches an address the other operations accept.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `name` | query | string, repeatable | no | Names to resolve, repeated: `?name=one&name=two`. A batch read — at least one and at most 32, each at most 160 characters and not blank. Every violation is refused with 400 rather than trimmed. |

Answers: `200` The requested reading of the active Release.; `400` The query is not one this Catalog can read.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/nodes/{canonical_id}`

**Read one complete Node** Operation id `readNode`.

The whole Node at one canonical address: every section, in order, with its prose and its references. This is the most expensive payload on the surface — prefer a Card when the publisher's claims are all you need.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `canonical_id` | path | string | yes | The Node's canonical id. Canonical ids are not guessable — reach one through resolveName, orient, or search. |
| `section` | query | string | no | Read one section by slug instead of the whole Node. An unknown slug is a 404, not an empty read. |

Answers: `200` The requested reading of the active Release.; `404` No such subject in the active Release.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/links/{canonical_id}`

**Page one Node's relationship occurrences** Operation id `readLinks`.

Every argued relationship touching one subject, inbound and outbound in the same page. There is deliberately no direction filter: each occurrence carries its own direction, so read the side you want off the page you already have rather than spending a second call.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `canonical_id` | path | string | yes | The subject whose relationships are read. |
| `direction` | query | string; default both; one of: both, in, out | no | Which side to read. The default carries both in one response and each occurrence states its own direction, so filtering here saves nothing but a field. |
| `limit` | query | integer; default 12; 1 to 50 | no | How many occurrences to carry per side. A bound, not a page: when it cuts, the view says so in `total`, `returned` and `truncated`, and the remainder is reached by raising this toward its maximum rather than by a cursor. |

Answers: `200` The requested reading of the active Release.; `404` No such subject in the active Release.; `422` A parameter value is outside its permitted range, or could not be parsed into its declared type. The two carry different bodies — see the schema.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/glossary`

**List the admitted glossary terms** Operation id `listGlossary`.

The complete working vocabulary of the active Release, one entry per admitted term, in the publisher's order.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `term` | query | string | no | Define one term instead of listing every term. Supplying it returns the same payload as defineTerm. |

Answers: `200` The requested reading of the active Release.; `400` The query is not one this Catalog can read.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/glossary/{term}`

**Define one glossary term** Operation id `defineTerm`.

Resolves one term to its definition. Reports an exact match, an ambiguity with the candidate terms that could have been meant, or a miss with near spellings — all three are successful payloads a caller can act on.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `term` | path | string | yes | The term to define, in a reader's own spelling. A miss is a successful payload carrying near spellings, never a 404. |

Answers: `200` The requested reading of the active Release.; `400` The query is not one this Catalog can read.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/glossary/{term_key}/usages`

**Find where one term is used** Operation id `readTermUsages`.

The published sections that lean on one term, addressed by the exact key a definition resolved to, so a reader can see a term at work rather than only defined. An unknown key reads no usages rather than resolving a second time.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `term_key` | path | string | yes | The exact Catalog key a definition resolved to — not a loose spelling. An unknown key reads no usages rather than resolving a second time. |
| `limit` | query | integer; default 12; 1 to 50 | no | How many usages to carry. A bound, not a page: when it cuts, the payload says so in `total`, `returned` and `truncated`. |

Answers: `200` The requested reading of the active Release.; `400` The query is not one this Catalog can read.; `422` A parameter value is outside its permitted range, or could not be parsed into its declared type. The two carry different bodies — see the schema.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/decisions`

**List or search the decision records** Operation id `listDecisions`.

The admitted decision summaries, optionally filtered by query. Decision records explain how the corpus came to be shaped the way it is; they are history and never override the live Release.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `query` | query | string | no | Narrow the listing to decision records matching these words. Omit it to list them all, in the publisher's order. |
| `limit` | query | integer; default 20; 1 to 50 | no | How many decision summaries to carry. A bound, not a page: the order is the publisher's, so this returns a prefix. |

Answers: `200` The requested reading of the active Release.; `400` The query is not one this Catalog can read.; `422` A parameter value is outside its permitted range, or could not be parsed into its declared type. The two carry different bodies — see the schema.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

### `GET /api/decisions/{canonical_id}`

**Read one complete decision record** Operation id `readDecision`.

One decision record in full: the question, the options weighed, and the verdict. This is where a ruling stated on a plate was actually argued, and the right place to take a disagreement.

| Name | In | Type | Required | What it does |
| --- | --- | --- | --- | --- |
| `canonical_id` | path | string | yes | The decision record's canonical id. A miss is a successful payload whose `outcome` is `not-found`, answered with 404. |

Answers: `200` The requested reading of the active Release.; `400` The query is not one this Catalog can read.; `404` No such subject in the active Release.; `503` The Catalog is unreachable. The address is fine; retry. Readiness is reported at /readyz.

## Pagination

Reads are bounded, not paged. `limit` caps one response; it does not select a window, and there is no offset, page number, or cursor to advance — no continuation state exists to carry. Ordering is the publisher's and is stable within one Release, so a bounded read is a prefix rather than a sample. Where a bound can cut, the payload reports it in-band; the remainder is reached by raising `limit` toward the maximum declared on the parameter, or by narrowing the subject. A client written for cursors should not be pointed here.