# Spore API > Agent-first B2B company intelligence: the Commons every organization researches against, each organization's own Companies and knowledge, and the durable work that runs on their behalf. One Operation registry, answered as REST under /api/v1. - Revision: 2026-09-06 - This guide: /api/v1/llms.txt - Contract: /api/v1/openapi.json - Reference pages: /docs/api - Every path below is relative to the origin that served this guide. ## Every request - **Key.** `Authorization: Bearer ` on every Operation. A key carries Capability scopes; an Operation below names the one it requires, and a key without it is refused `403`. - **Writes.** Every Operation whose posture is `write` requires an `Idempotency-Key` header. Reusing a key replays the original result and answers `Idempotency-Replayed: true`. Posture is not method: a POST that only reads is a read. - **Conditional writes.** Where an Operation requires `Spore-If-Match`, send the resource's current `ETag` in it; a missing one is refused `428`. A write carrying a standard conditional header (`If-Match`, `If-None-Match`, `If-Modified-Since`, `If-Unmodified-Since`, `If-Range`) is refused `400` (`conditional_header_unsupported`) before it runs: the CDN in front of the Service answers `If-Match` itself and may answer the others. Send the body's `etag`, since a compressed answer's `ETag` header may arrive weakened (`W/"…"`), which never matches. - **Credits.** Priced Operations debit the organization's wallet. A variable price is quoted per request and requires `maxCredits`; a refusal names the bound and the quote. - **Errors.** Every non-2xx body is `{ error, message }` plus modelled detail. Each Operation lists the statuses it documents. - **Paging.** Cursor reads take `cursor` and `limit` (default 50, maximum 100) and return an opaque `nextCursor`. - **Deprecation.** A deprecated Operation keeps answering and carries `Deprecation` and `Sunset` headers until it is removed. See Sunsets. ## Catalog ### catalog `GET /api/v1/catalog` — Read a vocabulary: tools, filters, knowledge, or NACE - Scope: any valid key - Posture: read - Success: 200 — The requested vocabulary - Errors: 400, 401, 429, 503 - Reference: /docs/api/catalog One discovery endpoint over four vocabularies, selected by `section`. `tools` lists available workflows, `filters` describes the search grammar, `knowledge` reports this organization's declared namespaces, and `nace` returns the NACE Rev 2.1 taxonomy. NACE also supports a compact text projection and a flat Class-level projection. Free. ## Keys ### key-create `POST /api/v1/keys` — Create an API key and reveal its secret once - Scope: `key:manage` - Posture: write (`Idempotency-Key` required) - Success: 201 — Created key policy and its one-time secret - Errors: 400, 401, 403, 409, 422, 429 - Reference: /docs/api/key-create Requires an explicitly delegated key:manage capability whose creator is still an organization owner or admin. Callers carrying any spend bounds cannot create keys: delegation must not multiply a rolling budget. An unbounded management key may grant requested scopes, including priced scopes with finite per-request and rolling-budget bounds. Child expiry cannot exceed the caller's expiry. A restricted caller must grant an explicit subset of its Operation allowlist and cannot delegate key:manage. Null allowedOperations permits every Operation allowed by scopes; [] permits none. The secret is returned only on initial success and is never persisted in the idempotency receipt. Replays return 409; revoke the created key and use a new request if the secret was lost. Free. ### key-revoke `POST /api/v1/keys/{keyId}/revoke` — Revoke an organization API key - Scope: `key:manage` - Posture: write (`Idempotency-Key` required) - Success: 200 — The key is revoked - Errors: 400, 401, 403, 404, 409, 422, 429 - Reference: /docs/api/key-revoke Requires key:manage and a creator who is still an organization owner or admin. The target must belong to the authenticated organization; missing and foreign keys both return 404. Revoking a recorded parent or transitive ancestor returns 403 key_ancestor_revocation_forbidden, including through revoked ancestors. Revoking an already revoked non-ancestor key succeeds without another policy event. Subsequent authentication with the revoked key is refused. Free. ## Wallet ### wallet `GET /api/v1/wallet` — Read the balance and this key's spend bounds - Scope: `wallet:read` - Posture: read - Success: 200 — The organization's wallet economics and the calling key's bounds - Errors: 401, 429 - Reference: /docs/api/wallet Current Balance plus optional Committed, Spendable, and period Spent totals. `keyBounds` carries this key's scopes, per-request ceiling, rolling budget, budget window, and remaining headroom; `budgetPeriodDays` and `budgetRemaining` are null when the key has no budget. The read is organization-wide. Free. ### wallet-transactions `GET /api/v1/wallet/transactions` — Page the organization's credit ledger - Scope: `wallet:read` - Posture: read - Success: 200 — One page of ledger rows, newest first - Errors: 400, 401, 422, 429 - Reference: /docs/api/wallet-transactions Every credit change, newest first, paged by opaque cursor. Pass `apiKeyId` to narrow the ledger to one principal's spend. Reads are organization-scoped. Free. ## Audit ### audit-calls `GET /api/v1/audit/calls` — Page the organization's Operation calls - Scope: `wallet:read` - Posture: read - Success: 200 — One page of Operation calls, newest first - Errors: 400, 401, 422, 429 - Reference: /docs/api/audit-calls Authenticated Operation calls, newest first, including refusals, free calls, and this read itself. A null status means no response has been recorded yet. Cost is actual net credits charged, not a quote; durable Job charges and refunds update the original call. Replays are separate zero-cost calls. Known revoked or expired credentials retain at most ten 401 samples per organization per rolling minute; further attempts increment suppressedAttempts on the latest sample without adding rows. This count is organization-wide, not attributed to the sample API key, and is zero when none. Other fields retain the original sampled call meaning. Filter by API key; opaque cursors preserve stable pagination. Organization-scoped. Free. ### audit-calls-export `POST /api/v1/audit/calls/export` — Export the organization's Operation calls - Scope: `export:run` - Posture: write (`Idempotency-Key` required) - Success: 200 — Export receipt with inline content or pending artifact delivery - Errors: 400, 401, 404, 409, 422, 429 - Reference: /docs/api/audit-calls-export Export selected calls, a key-filtered query, or the organization call Collection using explicit allowlisted fields. Small exports return inline bytes; larger exports return a durable artifact receipt. Free. ### audit-events `GET /api/v1/audit/events` — Page the organization's recorded acts - Scope: `wallet:read` - Posture: read - Success: 200 — One page of recorded acts, newest first - Errors: 400, 401, 422, 429 - Reference: /docs/api/audit-events The organization's durable chronology, newest first: Job and Run lifecycle, Exports, key policy changes, governance changes and balance movements, each with the actor that performed it and the ids it was about. This is the same log the console renders and the same rows an agent can page; opaque cursors preserve stable pagination under concurrent writes. Filter by an exact recorded kind; an unrecognised kind is refused with 422 and the message names the recorded vocabulary. Organization-scoped. Free. ### audit-events-export `POST /api/v1/audit/events/export` — Export the organization's recorded acts - Scope: `export:run` - Posture: write (`Idempotency-Key` required) - Success: 200 — Export receipt with inline content or pending artifact delivery - Errors: 400, 401, 409, 422, 429 - Reference: /docs/api/audit-events-export Export the kind-filtered chronology or the whole act Collection using explicit allowlisted fields; a field outside the allowlist is refused with 422. Small exports return inline bytes; larger exports return a durable artifact receipt whose rows are frozen at request time. Free. ## Companies ### company-mint `POST /api/v1/companies` — Mint Companies from your own data, or attach rows to Companies you hold - Scope: `company:write` - Posture: write (`Idempotency-Key` required) - Success: 200 — What each row did, in request order - Errors: 400, 401, 402, 404, 409, 422, 429, 500 - Reference: /docs/api/company-mint Imports up to 1000 rows. Each row needs a name, an operating country, at least one activity (ISIC Rev.5, NACE Rev.2.1, or NACE Rev.2 — converted to ISIC at the deepest level the code determines), and at least one identifier or domain. A row whose identifier a held Company already carries joins that Company; `into` joins a named Company; otherwise the row mints a new Company. A shared domain or an identical name and country is reported as `similar` and never decides. The whole batch is refused when any row is invalid, when an identifier belongs to two Companies, or when the batch would exceed the plan's Company allowance; `dryRun` returns the same plan and writes nothing. Free. A Company's Legal entity data is paid for once, inside the first priced request that touches it. ### companies `GET /api/v1/companies` — Page the organization's Companies - Scope: `company:read` - Posture: read - Success: 200 — One page of Companies - Errors: 400, 401, 422, 429, 500 - Reference: /docs/api/companies Lists the organization's Companies newest first under an opaque cursor, with their Core: name, country, activities, identifiers, and domains. Narrow by operating `country` or a name fragment `q`. Ids are opaque and never reused; a Company of another organization is invisible. Free. ### company-read `GET /api/v1/companies/{companyId}` — Read one Company - Scope: `company:read` - Posture: read - Success: 200 — The Company - Errors: 400, 401, 404, 422, 429, 500 - Reference: /docs/api/company-read Returns the Company's Core with its strong ETag, and its Legal entity section: nothing when the Company holds no Registry link, existence with the legal name, the status and the Inventory of the Namespaces it has plus the unlock price when it is verified but not unlocked, and the live registry record once it is. A deleted id and an id of another organization both read as not found. The ETag validates the Core for a conditional correction; it is not a cache validator, because the registry section is read live and changes without the Core changing. Free. ### company-correct `PATCH /api/v1/companies/{companyId}` — Correct a Company's Core under Spore-If-Match - Scope: `company:write` - Posture: write (`Idempotency-Key` required, `Spore-If-Match` required) - Success: 200 — The corrected Company - Errors: 400, 401, 404, 409, 422, 429, 500 - Reference: /docs/api/company-correct Changes the name or operating country in place; each supplied set of activities, identifiers, or domains replaces the whole set, so a Company never loses its last activity, its last identifier-or-domain, or its primary. An identifier that stays keeps its verification; one another Company holds is refused naming the holder. A stale `Spore-If-Match` is refused with the current Company and its ETag. Free. ### company-delete `DELETE /api/v1/companies/{companyId}` — Delete a Company - Scope: `company:write` - Posture: write (`Idempotency-Key` required) - Success: 200 — What was removed - Errors: 400, 401, 404, 409, 422, 429, 500 - Reference: /docs/api/company-delete Deletes the Company and its identifiers, activities, and domains outright; the id then reads as not found and the allowance count drops. Without `confirm=true` the call refuses with the counts it would remove. An Unlock grant on the Company's Legal entity is never deleted. Free. ### company-merge `POST /api/v1/companies/merge` — Fold one Company into another - Scope: `company:write` - Posture: write (`Idempotency-Key` required) - Success: 200 — What moved, what conflicted, and the surviving Company - Errors: 400, 401, 404, 409, 422, 429, 500 - Reference: /docs/api/company-merge Folds the absorbed Company into the survivor because both name the same Legal entity, and redirects the absorbed id to the survivor forever. Permitted only when the absorbed Company names no Legal entity or names the survivor's: two Companies bound to different entities are two businesses, and a verified Company absorbed into an unverified one is refused with the direction to merge instead. The absorbed Company's identifiers always move — one qualified value belongs to exactly one Company, so they cannot collide — and its domains and activities move unless the survivor already holds the same value. The survivor keeps its name, its country, and its primaries. `dryRun` reports the same plan and writes nothing. Unlock is untouched: a grant belongs to the Legal entity, not to a Company. There is no split and no undo. Free. A merge never refunds. ### company-legal-entity `POST /api/v1/companies/legal-entity` — Read Legal entity data for Companies you hold - Scope: `company:unlock` - Posture: write (`Idempotency-Key` required) - Success: 200 — Per-Company registry sections, what was charged, and the balance; or a dry run's quote - Errors: 400, 401, 402, 403, 404, 422, 429, 500, 503 - Reference: /docs/api/company-legal-entity Reads the live Registry record for up to 100 Companies, paying one credit for each Legal entity this organization has not unlocked before. `maxCredits` is mandatory spend consent and is checked against the worst-case quote before any Commons work; the whole request is refused rather than partly applied. `dryRun` returns that quote and which Companies it pays for, without reading the Commons, granting, or debiting; the real read charges the same, less what it cannot deliver: a Legal entity the Commons no longer carries, or one unlocked between the quote and the read. `namespaces` names the Namespaces whose Assertions ride beside each record, and only those the record's Inventory lists are read — read the Inventory off the locked section first, for free, and name its keys to get everything a Legal entity has, including the Namespaces a single Source owns. A Company with no Registry link is reported and never charged, an already-unlocked one is free forever, and a Legal entity the Commons no longer carries — including one withdrawn to a Tombstone — reads as absent. Variable price, quoted per request: up to 100 credits per call. 1 credit per Legal entity not yet unlocked, once, forever. Unverified and already-unlocked Companies are free. ### company-lookup `POST /api/v1/companies/lookup` — Find Legal entities in the Commons - Scope: `company:read` - Posture: read - Success: 200 — Commons candidates, best match first - Errors: 400, 401, 422, 429, 500, 503 - Reference: /docs/api/company-lookup Searches the Commons by name, by registration identifier, or both, and returns the Legal entities it carries. It mints nothing and unlocks nothing: each candidate reports whether this organization already holds a Company bound to it, so the caller decides what to mint (`POST /companies`) and what to pay to read (`POST /companies/legal-entity`). Free. ### company-promote `POST /api/v1/companies/promote` — Promote a declared current Fact into Company Core - Scope: `company:write` - Posture: write (`Idempotency-Key` required) - Success: 200 — One promotion outcome for each target Company - Errors: 400, 401, 404, 409, 422, 429, 500 - Reference: /docs/api/company-promote Adds each target Company's current Fact for one field declared with `promotes` to its Core, without replacing any existing value or primary. Domain values and qualified Identifier values are normalized before insertion. A registration Identifier must use a scheme the country's Commons publishes; it is verified inline and binds an unbound Company when carried. A Legal entity another Company already names is reported as a conflict, and a different entity than the target already names is reported as a mismatch; promotion never folds or rebinds Companies. Each changed Company's version and updated time move, while the immutable source Fact retains its producer and API-key/user attribution. `dryRun` returns the same per-Company outcomes and writes nothing. Free. ## Knowledge ### namespace-declare `POST /api/v1/namespaces` — Declare a namespace and its fields before recording into them - Scope: `knowledge:write` - Posture: write (`Idempotency-Key` required) - Success: 200 — The declaration, and what this call changed - Errors: 400, 401, 409, 422, 429, 500 - Reference: /docs/api/namespace-declare Declares what your organization wants to know about Companies: a namespace with typed fields, each carrying its unit, dimension, freshness, and meaning. Recording into a field that is not declared is refused, so this call comes first. The same call amends: a field you already declared is left alone, a new one is added, and a description or freshness you changed your mind about is updated — which makes it safe to send your whole catalog on every boot. What it never does is remove a field by omission, or change what a field *is* once a Fact references it: name, type, unit, dimension, and promotion are then fixed and the fix for a mistake is a new field. Caps are 1000 namespaces and 50 fields each. Free. ### namespaces `GET /api/v1/namespaces` — Read your Catalog - Scope: `company:read` - Posture: read - Success: 200 — Your namespaces and their declared fields - Errors: 401, 429, 500 - Reference: /docs/api/namespaces Returns every namespace this organization can record into: its own declarations, and the native ones the Spore tools own. A field marked `frozen` has Facts standing on it, so its type, unit, dimension, and promotion are fixed. The Catalog is private to the organization and never shared-cached. Free. ### namespace-delete `DELETE /api/v1/namespaces/{namespaceName}` — Delete a declaration while nothing stands on it - Scope: `knowledge:write` - Posture: write (`Idempotency-Key` required) - Success: 200 — What was removed - Errors: 400, 401, 404, 409, 422, 429, 500 - Reference: /docs/api/namespace-delete Deletes one field with `?field=`, or the whole namespace without it. A field a Fact references is refused naming it: the declaration is what makes a recorded value readable, so it outlives nothing. Removing a namespace's last field removes the namespace. A native namespace is never deletable. Free. ### record `POST /api/v1/record` — Record what you observed about a Company or concluded about a Segment - Scope: `knowledge:write` - Posture: write (`Idempotency-Key` required) - Success: 200 — What was recorded, and which values are now current - Errors: 400, 401, 404, 409, 422, 429, 500 - Reference: /docs/api/record Appends up to 200 observations about one subject: a Company with `companyId`, or a Segment with `segmentId` when the conclusion is about the set rather than about any one member. Exactly one of the two — a Fact about both is a caller that has not decided what it observed. Every field must be declared first and every value is validated against its declared type, so a number field cannot receive "about 5M". A field you looked at and found nothing for is recorded with `absent: true` — knowledge, not a gap, and coverage reports it as checked rather than missing. Facts are appended and never edited: the newest observation becomes the current value, an older observation arriving late does not displace a newer one, and `pin: true` fixes one observation as current until `pin: false` releases it. Set `observedAt` when you learned something about an earlier moment. A conclusion about a Segment cites the Jobs it was reduced from with `{ kind: "job", jobId }` evidence. Native namespaces are refused: a Fact in one is a Spore run's receipt. Free. ### company-facts `GET /api/v1/companies/{companyId}/facts` — Read everything you know about one Company - Scope: `company:read` - Posture: read - Success: 200 — Current values with their history - Errors: 400, 401, 404, 422, 429, 500 - Reference: /docs/api/company-facts Returns the current value of every field this organization has observed about the Company, each with who produced it, when it was observed, the evidence behind it, whether the declaration's freshness has lapsed, and the full history underneath. A Fact that cites nothing says so with an empty `evidence`. Fields never observed are absent from the response — `POST /coverage` is the door that asks what is missing over a set. Free. ### segment-facts `GET /api/v1/segments/{segmentId}/facts` — Read what you have concluded about one Segment - Scope: `segment:read` - Posture: read - Success: 200 — Current conclusions with their history - Errors: 400, 401, 404, 422, 429, 500 - Reference: /docs/api/segment-facts Returns the current value of every field this organization has recorded about the Segment itself — reduce knowledge, the conclusions that are about the set rather than about any one member — each with who recorded it, when, the evidence behind it including the Jobs it was reduced from, whether its declaration's freshness has lapsed, and the full history underneath. Members' own Facts are read per Company; `POST /coverage` is the door that asks what a set is missing. Free. ### coverage `POST /api/v1/coverage` — Measure requested fields over a set of Companies - Scope: `company:read` - Posture: read - Success: 200 — Coverage of the requested fields over the resolved set - Errors: 400, 401, 404, 422, 429, 500 - Reference: /docs/api/coverage Reports current, stale, explicitly checked-none, and never-observed counts for only the requested Catalog fields, over either an explicit list of Companies or a Segment's live members. A `registry.*` reference is answered in `commons` instead: coverage of Legal entity data is per Commons Namespace from each Legal entity's Inventory, not per field, and it costs no Unlock, because reading an Inventory never triggers one. This read uses POST because an explicit target may carry up to 10,000 Company ids; its read posture means it takes no Idempotency-Key. Free. ## Search ### search `POST /api/v1/search` — Search the Commons: count, analytics, and a minted sample - Scope: `search:run` - Posture: write (`Idempotency-Key` required) - Success: 200 — The receipt, the population's count and analytics, the minted sample, the charge, and the expiry; or a dry run's quote - Errors: 400, 401, 402, 403, 422, 429, 503 - Reference: /docs/api/search Runs a filter AST against the live Commons and answers with the population's count, its full analytics, and a sample of matching Legal entities minted as Companies of this organization — verified and unlocked from birth, with Core pre-filled from the registry. The charge is `max(5, newly unlocked)`: the floor pays for the count and analytics, and every Legal entity this organization has not unlocked before costs one credit, once, forever. A Company it already holds is unlocked in place rather than duplicated. An identical request replayed inside the receipt's window returns the original sample for nothing. The quote is the worst case, `max(5, sampleSize)`, computed before anything is read or written; the call is refused whole when it exceeds `maxCredits` or the key's bounds, and the charge never exceeds it. `dryRun` returns the quote without reading the Commons, minting, unlocking, or charging. Unlock the whole population with `POST /api/v1/search/{searchId}/unlock`. Variable price, quoted per request: up to 100 credits per call. Charged max(5, newly unlocked Legal entities); an active receipt replays for 0. ### search-unlock `POST /api/v1/search/{searchId}/unlock` — Unlock every Legal entity a search matched - Scope: `search:run` - Posture: write (`Idempotency-Key` required) - Success: 200 — What the population resolved to, what was minted and unlocked, and the charge - Errors: 400, 401, 402, 403, 404, 410, 422, 429, 500, 503 - Reference: /docs/api/search-unlock Mints every Legal entity the receipt's filter matches as a Company of this organization and unlocks it, at one credit per entity not unlocked before. The quote is computed from the live population before anything is written; the call is refused whole — never partly applied — when it exceeds `maxCredits`, the plan's Company allowance, or the balance, and `dryRun` returns the same quote without minting, unlocking, or charging. Two kinds of match are left alone and never charged, and both are counted in the response: `conflicts`, where an identifier of the entity belongs to a Company that already names a different Legal entity (a merge, not an unlock), and `incomplete`, where the registry record cannot make a Company's Core. A population above 50,000 entities is refused: narrow the filter and search again. The Companies it creates are listed through `GET /api/v1/companies`. Variable price, quoted per request. 1 credit per Legal entity not yet unlocked, once, forever. Already-unlocked entities are free. ## Commons ### commons.publish `POST /api/v1/commons/publish` — Publish a staged Commons Generation - Scope: `commons:publish` - Posture: write (`Idempotency-Key` required) - Success: 200 — The published Generation's Directory document - Errors: 400, 401, 403, 409, 422, 429, 500 - Reference: /docs/api/commons.publish Requires a platform-scoped commons:publish key; organization keys are refused regardless of scopes. The Service validates the staged Generation and atomically publishes its data aliases and Directory. A gate refusal changes no aliases. Free. ### commons.rollback `POST /api/v1/commons/rollback` — Restore the retained previous Commons Generation - Scope: `commons:publish` - Posture: write (`Idempotency-Key` required) - Success: 200 — The published Generation's Directory document - Errors: 400, 401, 403, 409, 422, 429, 500 - Reference: /docs/api/commons.rollback Requires a platform-scoped commons:publish key; organization keys are refused regardless of scopes. Publishes the retained previous Generation for this Jurisdiction. Send a fresh Idempotency-Key for each intentional rollback, and reuse it only to retry that rollback. Free. ## Segments ### segment-create `POST /api/v1/segments` — Name a live filter over your Companies - Scope: `segment:write` - Posture: write (`Idempotency-Key` required) - Success: 201 — The Segment - Errors: 400, 401, 402, 422, 429, 500 - Reference: /docs/api/segment-create Stores a name and a filter, and nothing else. Members are whichever Companies match when you ask, so there is no count here, no snapshot, and no refresh: editing the filter changes membership immediately. Every field the filter names is validated against your own vocabulary — Core, your Catalog, and the registry field map — and an undeclared name is refused. Creating a Segment evaluates nothing. Free. ### segments `GET /api/v1/segments` — Page the organization's Segments - Scope: `segment:read` - Posture: read - Success: 200 — One page of Segments - Errors: 400, 401, 422, 429, 500 - Reference: /docs/api/segments Lists Segments newest first under an opaque cursor, each with its name, its filter, and its ETag. No member counts: counting a set is a read of the set. Free. ### segment `GET /api/v1/segments/{segmentId}` — Read a Segment's name and filter - Scope: `segment:read` - Posture: read - Success: 200 — The Segment - Errors: 400, 401, 404, 429, 500 - Reference: /docs/api/segment Returns the Segment and its ETag. Members, counts, and coverage are separate reads, because each of them is a question about live data rather than a property of the row. Free. ### segment-update `PATCH /api/v1/segments/{segmentId}` — Rename a Segment, or change what it means, under Spore-If-Match - Scope: `segment:write` - Posture: write (`Idempotency-Key` required, `Spore-If-Match` required) - Success: 200 — The edited Segment - Errors: 400, 401, 404, 409, 422, 428, 429, 500 - Reference: /docs/api/segment-update Changes the name, the filter, or both. Editing the filter changes membership immediately — there is nothing to rebuild and nothing goes stale. A stale `Spore-If-Match` is refused with the current Segment and its ETag. Free. ### segment-delete `DELETE /api/v1/segments/{segmentId}` — Delete a Segment - Scope: `segment:write` - Posture: write (`Idempotency-Key` required) - Success: 200 — The deleted Segment's id - Errors: 400, 401, 404, 409, 422, 429, 500 - Reference: /docs/api/segment-delete Hard, and refused without `confirm=true`, reporting how much reduce knowledge it would remove. Echo that count as `reduceFacts` when confirming to refuse deletion if it changed. Company Facts are never touched: they belong to the Companies, not to the set that named them. Free. ### segment-companies `GET /api/v1/segments/{segmentId}/companies` — Page a Segment's members, with the exact count - Scope: `segment:read` - Posture: read - Success: 200 — One page of members and the exact total - Errors: 400, 401, 404, 422, 429, 500, 503 - Reference: /docs/api/segment-companies Evaluates the filter now and returns one page of members newest first under an opaque cursor, plus the exact total of the whole set. Registry predicates are evaluated in the Commons over the Legal entities you have unlocked, so a verified-but-locked Company never appears and membership can never reveal data you have not paid for. Reading your own set is not an acquisition. Free. ## Enrichment ### enrich `POST /api/v1/enrich` — Run a native enrichment - Scope: `enrich:run` - Posture: write (`Idempotency-Key` required) - Success: 201 — The accepted Job and compatibility launch, or a dry-run quote - Errors: 400, 401, 402, 403, 404, 409, 422, 429, 500, 503 - Reference: /docs/api/enrich Runs one native tool against an explicit list of the organization's own Company ids. Every tool runs against a Company and reads its Core — name, country, primary Domain, Activity, Identifier — from the target, so a request states only the tool's own settings and, in `context`, the Catalog fields to resolve for each target. A repeated id is one target. A Company this organization does not hold is refused as not found. A target whose Company lacks a Core input the selected tool requires is refused at admission: it appears in `refused` with the slots it could not supply, gets no Run, and costs nothing, while the rest of the launch proceeds. When every target is refused the whole request is refused with `missing_input`. The quote is `runs + unlocks` — research is the door that pays for the Legal entity behind a verified target, one credit, once, forever — and it is refused whole against `maxCredits`. Set `dryRun` for a quote that commits nothing. Variable price, quoted per request. ### enrichment `GET /api/v1/enrichments/{enrichmentId}` — Poll an enrichment - Scope: `enrich:read` - Posture: read - Success: 200 — Enrichment lifecycle and outcome - Errors: 400, 401, 404, 429, 503 - Reference: /docs/api/enrichment Returns lifecycle and per-item outcome separately for one enrichment or launch. Another organization's resource is a 404. Free. ### launch-items `GET /api/v1/enrichments/{enrichmentId}/items` — List per-item enrichment outcomes - Scope: `enrich:read` - Posture: read - Success: 200 — A page of enrichment items - Errors: 400, 401, 404, 422, 429 - Reference: /docs/api/launch-items Lists child enrichments in stable target order with lifecycle and outcome as separate fields. Outputs are opt-in via `include=output`, and `ref` echoes the caller's per-target correlation key. Free. ### cancel `POST /api/v1/enrichments/{enrichmentId}/cancel` — Cancel an enrichment launch - Scope: `enrich:run` - Posture: write (`Idempotency-Key` required) - Success: 200 — The cancelled launch - Errors: 400, 401, 403, 404, 409, 429, 500, 503 - Reference: /docs/api/cancel Requests cancellation of a native launch. Refunds are decided by the canonical terminal transition, not by this operation. Free. ## Workflows ### job-targets `GET /api/v1/jobs/{jobId}/targets` — Page a Job's frozen target list - Scope: `enrich:read` - Posture: read - Success: 200 — One page of targets, in submission order - Errors: 400, 401, 404, 422, 429 - Reference: /docs/api/job-targets The ordered Companies this Job was admitted over, with the watermarks it was computed under: the admission transaction's own time, and the Commons Generation this Job read for each Jurisdiction the Commons served. The list is frozen at admission: deleting a target, merging it into another Company, or changing the Segment that selected it never rewrites the receipt, so a target id here may no longer name a live Company. Free. ## Events ### events `GET /api/v1/events` — Follow the organization's durable events stream - Scope: `events:read` - Posture: read - Success: 308 — The events stream destination is available. - Errors: 401, 403, 429, 503 - Reference: /docs/api/events Redirects to the externally routable workflow engine SSE stream. A client must carry its API key across the redirect, which curl does with --location-trusted and an EventSource cannot do at all, and keeps its Last-Event-ID cursor for resumable delivery. Free. ## Sunsets No Operation is deprecated at this revision.