# Sponge reference

The agent API operation by operation, the graph record kinds, public URIs, the glossary, error codes, limits, and the changelog.

Docs edition 2026.09. Reviewed 2 September 2026.

## API

Every agent-facing operation, its scopes, headers, and statuses, generated from the OpenAPI document.

Generated from the OpenAPI 3.1 document (Sponge API 1.0.0); operator-only operations are omitted.

Canonical reads return a bare `Sponge-Revision`; semantic writes send it back as `Sponge-If-Revision`. Every write needs an `Idempotency-Key`. A weak `ETag` validates GET caches only. A known path called with an unimplemented method answers a JSON 405 with an `Allow` header.

#### GET /api/v1/auth

Returns the bounded delegated agent principal, its remaining request budget, and its per-minute, daily, and research-run budgets for the bearer token. A document-bound credential also learns its exact documentRef and browserHref here.

- Scope: Requires a valid token; no additional scope.
- Token boundary: any
- Parameter `X-Request-Id` (header): Optional client correlation id. It is echoed as meta.clientRequestId; meta.requestId and X-Request-Id are always server-minted.
- Response 200 (application/json): The bounded delegated agent principal, remaining request budget, and budgets.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### GET /api/v1/documents

Lists document summaries within this credential's boundary, newest updatedAt first. An account-wide credential sees every API-reachable document it owns; a document-bound credential sees only its bound document. Bodies are not included; read each document for content and its Sponge-Revision.

- Scope: Requires document:read.
- Token boundary: any
- Parameter `limit` (query): Maximum summaries in the page, from 1 to 50. Defaults to 20.
- Parameter `cursor` (query): The nextCursor from the previous documents page, sent back unchanged. A cursor from another list or credential is rejected with 400.
- Response 200 (application/json): One bounded page of document summaries.
- Response 400 (application/json): The limit or cursor query is malformed or belongs to another list.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### POST /api/v1/documents

Creates a private document through an account-wide credential. A document-bound credential cannot create another document.

- Scope: Requires document:create.
- Token boundary: account-wide
- Parameter `Idempotency-Key` (header, required)
- Request body: `DocumentCreateRequest` as application/json
- Response 200 (application/json): An exact idempotent create replay returned the existing private document.
- Response 201 (application/json): The private document was created idempotently.
- Response 400 (application/json): INVALID_REQUEST or IDEMPOTENCY_REQUIRED: the body, headers, or query do not match this contract.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 409 (application/json): The idempotency key is bound to different create intent.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### GET /api/v1/documents/{documentRef}

Returns the private document in one of three representations chosen by the format query. rich-json (the default) is the exact canonical editor JSON; blocks is a flat list of authored blocks, each with its stable ID, parent, index, and its own Markdown, so reads and mutations share one vocabulary; markdown is a whole-document Markdown projection whose structural losses are counted in X-Sponge-Markdown-Loss-Count. Every representation carries the same bare Sponge-Revision for later writes. Send If-None-Match with a prior weak ETag to receive 304 when the document is unchanged.

- Scope: Requires document:read.
- Token boundary: any
- Parameter `documentRef` (path, required)
- Parameter `If-None-Match` (header): One or more weak ETag values from earlier canonical reads. When one matches the current representation the response is 304 with the current Sponge-Revision and no body.
- Parameter `format` (query): The representation to return. rich-json is the exact editor JSON; blocks is the flat block-addressed list; markdown is text/markdown with a loss count.
- Response 200 (application/json, text/markdown): The document as exact rich JSON, as a flat block list, or as loss-reported Markdown.
- Response 304: A supplied If-None-Match value matched the current canonical representation. The body is empty; Sponge-Revision and ETag describe the current representation.
- Response 400 (application/json): The format query is not rich-json, blocks, or markdown.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 404 (application/json): NOT_FOUND: nothing is visible to this credential at that reference. Absence and out-of-boundary references are indistinguishable.
- Response 409 (application/json): CONFLICT: the document holds blocks outside the Markdown grammar, so the blocks or markdown representation is unavailable. Read format=rich-json.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### POST /api/v1/documents/{documentRef}/mutations

Applies one bounded semantic document mutation against an exact Sponge-If-Revision. An exact retry reuses its original idempotency key, body, and revision.

- Scope: Requires document:write.
- Token boundary: any
- Parameter `documentRef` (path, required)
- Parameter `Idempotency-Key` (header, required)
- Parameter `Sponge-If-Revision` (header, required): The exact bare Sponge-Revision read before this command. An exact idempotent retry reuses its original revision even if the resource has since advanced.
- Request body: `DocumentMutationRequest` as application/json
- Response 200 (application/json): The semantic document mutation was applied idempotently.
- Response 400 (application/json): INVALID_REQUEST or IDEMPOTENCY_REQUIRED: the body, headers, or query do not match this contract.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 404 (application/json): NOT_FOUND: nothing is visible to this credential at that reference. Absence and out-of-boundary references are indistinguishable.
- Response 409 (application/json): The idempotency key is bound to different intent or the semantic mutation conflicts with the exact document structure.
- Response 412 (application/json): The supplied exact document revision is stale.
- Response 428 (application/json): A semantic document mutation requires Sponge-If-Revision.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### GET /api/v1/research-jobs

Lists summaries of the research jobs this credential started, newest updatedAt first. A job is visible only to the credential that created it, so a fresh token starts with an empty list.

- Scope: Requires one of research:read, research:run.
- Token boundary: any
- Parameter `limit` (query): Maximum summaries in the page, from 1 to 50. Defaults to 20.
- Parameter `cursor` (query): The nextCursor from the previous research-jobs page, sent back unchanged. A cursor from another list or credential is rejected with 400.
- Response 200 (application/json): One bounded page of research-job summaries.
- Response 400 (application/json): The limit or cursor query is malformed or belongs to another list.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### POST /api/v1/research-jobs

Starts durable research in an existing exact document, or creates a document only for an account-wide credential. A document-bound credential must use its bound document reference.

- Scope: Requires inquiry:create, knowledge:propose, research:run.
- Token boundary: any when spaceRef.kind=document; account-wide when spaceRef.kind=new-document
- Parameter `Idempotency-Key` (header, required)
- Request body: `ResearchReportSpec` as application/json
- Response 202 (application/json): The durable research job was accepted.
- Response 400 (application/json): INVALID_REQUEST or IDEMPOTENCY_REQUIRED: the body, headers, or query do not match this contract.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 404 (application/json): NOT_FOUND: the target document is not visible to this credential, whether missing or outside its space.
- Response 409 (application/json): IDEMPOTENCY_CONFLICT: the key is bound to a different research request.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### GET /api/v1/research-jobs/{jobId}

Returns canonical research-job state for one durable job. A job outside this credential's boundary answers 404, never 403. Send If-None-Match with a prior weak ETag to receive 304 when the job is unchanged.

- Scope: Requires one of research:read, research:run.
- Token boundary: any
- Parameter `jobId` (path, required)
- Parameter `If-None-Match` (header): One or more weak ETag values from earlier canonical reads. When one matches the current representation the response is 304 with the current Sponge-Revision and no body.
- Response 200 (application/json): Canonical research job state.
- Response 304: A supplied If-None-Match value matched the current canonical representation. The body is empty; Sponge-Revision and ETag describe the current representation.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 404 (application/json): NOT_FOUND: nothing is visible to this credential at that reference. Absence and out-of-boundary references are indistinguishable.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### GET /api/v1/research-jobs/{jobId}/events

Returns a bounded monotonic event page (application/json) or, when Accept includes text/event-stream, a resumable notification stream. Each stream frame is "id: <eventId>", "event: research-job", and "data: <ResearchJobEvent JSON>"; the stream opens with "retry: 5000", writes a ": keep-alive" comment while idle, and closes after a terminal event, 1024 events, or 20 seconds (the route allows 30). Resume with Last-Event-ID; the canonical job read stays authoritative.

- Scope: Requires one of research:read, research:run.
- Token boundary: any
- Parameter `jobId` (path, required)
- Parameter `after` (query): Return events with an eventId greater than this decimal sequence.
- Parameter `Last-Event-ID` (header): Resumes a text/event-stream response after this eventId. It is the decimal event sequence as a string, exactly as the id: frame field carried it.
- Response 200 (application/json, text/event-stream): A bounded monotonic event page or resumable notification stream.
- Response 400 (application/json): The after query or Last-Event-ID header is not one valid event cursor.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 404 (application/json): NOT_FOUND: nothing is visible to this credential at that reference. Absence and out-of-boundary references are indistinguishable.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### POST /api/v1/research-jobs/{jobId}/cancellations

Cancels one research job idempotently. After success, the terminal receipt may replay with the post-cancellation revision.

- Scope: Requires research:run.
- Token boundary: any
- Parameter `jobId` (path, required)
- Parameter `Idempotency-Key` (header, required)
- Parameter `Sponge-If-Revision` (header, required): The exact bare current research-job Sponge-Revision. After this cancellation key has already succeeded for this job, the terminal receipt may replay with the post-cancellation revision; a different key or a not-yet-cancelled stale command does not bypass the precondition.
- Request body: `The fixed cancellation body.` as application/json
- Response 200 (application/json): The idempotently cancelled research job and cancellation receipt.
- Response 400 (application/json): INVALID_REQUEST or IDEMPOTENCY_REQUIRED: the body, headers, or query do not match this contract.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 404 (application/json): NOT_FOUND: nothing is visible to this credential at that reference. Absence and out-of-boundary references are indistinguishable.
- Response 409 (application/json): CONFLICT: the job is terminal or the cancellation was rejected.
- Response 412 (application/json): The supplied research-job revision is stale.
- Response 428 (application/json): Cancellation requires Sponge-If-Revision.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### GET /api/v1/research-jobs/{jobId}/report

Returns the exact rich research report or its loss-reported Markdown projection after the report is ready. The rich JSON export returns the whole document and therefore also requires document:read; the Markdown projection needs only a research read scope. Before the report is ready it returns retryable REPORT_NOT_READY with Retry-After. Send If-None-Match with a prior weak ETag to receive 304 when the report is unchanged.

- Scope: Requires one of research:read, research:run. With format=rich-json, also document:read.
- Token boundary: any
- Parameter `jobId` (path, required)
- Parameter `format` (query, required): rich-json for the exact report envelope, markdown for the text projection.
- Parameter `If-None-Match` (header): One or more weak ETag values from earlier canonical reads. When one matches the current representation the response is 304 with the current Sponge-Revision and no body.
- Response 200 (application/json, text/markdown): The exact rich report or its loss-reported Markdown projection.
- Response 304: A supplied If-None-Match value matched the current canonical representation. The body is empty; Sponge-Revision and ETag describe the current representation.
- Response 400 (application/json): The format query is not exactly one of rich-json or markdown.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 404 (application/json): NOT_FOUND: nothing is visible to this credential at that reference. Absence and out-of-boundary references are indistinguishable.
- Response 409 (application/json): REPORT_NOT_READY: the job has not staged a report yet. The error is retryable; honor Retry-After and poll the canonical job until artifacts.report is present. CONFLICT: the report binding is inconsistent.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### POST /api/v1/proposals

Submits a bounded knowledge proposal. Standalone submission requires a live research-job agent run, so every well-formed request currently returns 409 AGENT_RUN_REQUIRED without charging the request budget.

- Scope: Requires knowledge:propose.
- Token boundary: exact-space when spaceRef
- Activation: blocked; every authenticated request answers 503 without charging the request budget until the surface is activated.
- Parameter `Idempotency-Key` (header, required)
- Request body: `ProposalRequest` as application/json
- Response 400 (application/json): INVALID_REQUEST or IDEMPOTENCY_REQUIRED: the body, headers, or query do not match this contract.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 409 (application/json): AGENT_RUN_REQUIRED: standalone proposal submission requires a live research-job agent run.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): TEMPORARILY_UNAVAILABLE: a dependency was unavailable; retry after Retry-After.
- Response default (application/json): A typed Sponge API error.

#### GET /api/v1/public/artifacts/{kind}/{artifactId}/{revision}

Returns an exact double-authorized public graph projection for a released Entity, Inquiry, or Edition. No bearer token is required.

- Scope: No token required.
- Parameter `kind` (path, required): The artifact kind.
- Parameter `artifactId` (path, required): The artifact identifier matching its kind prefix.
- Parameter `revision` (path, required): The SHA-256 revision of the released projection.
- Response 200 (application/json): An exact double-authorized public graph projection.
- Response 404 (application/json): NOT_FOUND: no released projection exists at that exact kind, identity, and revision.
- Response default (application/json): A typed Sponge API error.

#### GET /api/v1/reviews/{reviewRef}

Reads review metadata when review egress is activated. Until that join is complete every authenticated request returns 503 without charging the request budget.

- Scope: Requires review:read.
- Token boundary: any
- Activation: blocked; every authenticated request answers 503 without charging the request budget until the surface is activated.
- Parameter `reviewRef` (path, required): The krvw_ review reference.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): Review metadata egress is activation-blocked.
- Response default (application/json): A typed Sponge API error.

#### POST /api/v1/search

Searches public or private knowledge when the requested index is activated. Until those indexes are joined every authenticated request returns 503 without charging the request budget.

- Scope: With scope.kind=public, also public:read. With scope.kind=space, also knowledge:read.
- Token boundary: any when scope.kind=public; exact-space when scope.kind=space
- Activation: blocked; every authenticated request answers 503 without charging the request budget until the surface is activated.
- Request body: `SearchRequest` as application/json
- Response 400 (application/json): INVALID_REQUEST or IDEMPOTENCY_REQUIRED: the body, headers, or query do not match this contract.
- Response 401 (application/json): AUTH_REQUIRED or AUTH_AMBIGUOUS: no valid bearer credential, or a bearer sent together with a session cookie.
- Response 403 (application/json): FORBIDDEN: the credential lacks a required scope or crosses the operation's credential boundary. A reference outside the boundary answers 404, not 403.
- Response 429 (application/json): The delegated request or research budget is exhausted.
- Response 503 (application/json): Search is activation-blocked until its released/private indexes are joined.
- Response default (application/json): A typed Sponge API error.

## Record kinds

The immutable records that carry identity, meaning, evidence, review, rights, and publication.

- Activity: An attributable action such as import, proposal, review, transformation, or publication.
- Assertion: An attributable stance toward one Statement for a declared purpose and Context.
- Context: A precise boundary for time, place, language, perspective, version, or scenario.
- Dependency manifest: The complete ordered set of exact records required to reproduce an edition.
- Edition: An immutable synthesis whose passages retain exact support and policy dependencies.
- Entity: A durable identity anchor independent of its labels, types, and external identifiers.
- Evidence: A typed account of how a source, observation, selector, or method bears on an Assertion.
- Identity operation: A reviewed merge, split, redirect, quarantine, rekey, or tombstone over identity anchors.
- Inquiry: A human question and the bounded investigation it initiates.
- Inquiry event: One append-only step in an Inquiry, including a gap, observation, proposal, or decision.
- Review decision: A human decision over an exact proposed effect under one review purpose.
- Rights decision: A purpose-bound decision describing where an exact subject may be disclosed.
- Schema: An immutable definition for a concept, predicate, unit, mapping, or extension value.
- Shape: A composable validation and projection lens for one use, domain, or audience.
- Statement: An immutable proposition with a subject, predicate, typed object, and qualifiers.
- Type membership: Evidence-bearing membership of an Entity in a versioned concept.
- View: A purpose-bound specification for selecting and presenting exact graph state.
- Vocabulary: A versioned, owned collection of concepts, predicates, units, mappings, and Shapes.

## URIs

The public locator patterns and how identity stays separate from labels, revisions, and releases.

- Edition: `https://sponge.computer/k/edition/<edition-id>/<edition-digest>`
- Entity: `https://sponge.computer/k/entity/<entity-id>/<graph-revision>`
- Inquiry: `https://sponge.computer/k/inquiry/<inquiry-id>/<graph-revision>`

Every public page is also available as Markdown by adding `.md` to its address or requesting it with `Accept: text/markdown`.

## Glossary

The one name Sponge uses for each object, with its definition.

- Document: A private, versioned rich research workspace composed of stable nested blocks.
- Block: A durable, document-scoped unit of rich content. Moving or nesting a block does not change its identity.
- Space: The private knowledge boundary that holds a document's Inquiries, graph records, proposals, and reviews. The evidence picker searches the current document's space; nothing private crosses from one space to another.
- Lease: A short-lived, exclusive right to change one block or to decide one review item. The server checks the lease before it applies an edit or a decision. A selected block is not a lease, and an expired lease is refused rather than forced.
- Grant: A named person's bounded access to one document or block. Sign-in and a live grant are both required; a link alone never grants access.
- Source: An Entity classified as a citable information resource through reviewed vocabulary and evidence.
- Citation: A document reference to exact graph evidence, with its bearing, selector, Context, and graph revision.
- Excerpt: A short passage copied exactly from a source, with the date it was retrieved, that a reader can inspect beside the claim it supports.
- Claim: A reviewed statement about the world that a document or edition passage rests on. A claim whose sources carry no usable excerpt is reported as a gap instead of a finding.
- Inquiry: A human question with a private, append-only trail of research events, gaps, proposals, and decisions.
- Entity: A durable identity anchor for something that can be referred to, independent of its labels, types, and external identifiers.
- Document proposal: An agent's proposed change to the text or structure of a document. It changes nothing until a person applies it, and it never touches the knowledge graph.
- Knowledge proposal: An agent's exact, bounded change set for the knowledge graph. It has no authority until a person reviews it.
- Promotion review: The second, separate review of an accepted research effect for the public-encyclopedia purpose. Acceptance for research use never implies promotion.
- Shape: A versioned, composable validation and projection lens for one purpose or domain.
- Graph revision: The identifier of one exact state of a space's knowledge graph. Citations, released entity and Inquiry pages, and edition dependency manifests pin a graph revision so later changes cannot rewrite what they meant.
- Edition: An immutable synthesis whose passages and complete dependencies have passed human review.
- Publication enablement: The explicit decision by a space owner that editions from that space may be released. Without it, no edition from the space can receive a public locator, whatever has been accepted.
- Release: The explicit public binding between an eligible edition, entity, or Inquiry and its canonical /k locator.
- Public page: A server-rendered page anyone can read without a session: a released edition, entity, or Inquiry under /k, or a published document or block.
- Research note: A dated essay on sponge.computer that explains one product mechanism with primary sources; not a knowledge page and never generated by a model.
- Artifact: The docs' superset term for a released edition, entity, or Inquiry, the three kinds a /k locator can name.

## Errors

Every error code the API can return, its HTTP status, and what to do next.

| Code | HTTP status | Meaning | What to do |
| --- | --- | --- | --- |
| `INVALID_REQUEST` | 400 | The request did not match the published schema or size limits. | Compare the body, headers, and query with OpenAPI, then send a corrected request. |
| `AUTH_REQUIRED` | 401 | No valid Sponge agent credential arrived. | Create a token on the Agent access page and send it as Authorization: Bearer. |
| `AUTH_AMBIGUOUS` | 401 | A bearer token and a browser session were presented together. | Send one bearer token without a Suite session cookie. |
| `FORBIDDEN` | 403 | The credential lacks the scope or the document boundary for this operation. | Use a token with the required scope, or one bound to this document. |
| `NOT_FOUND` | 404 | No resource is visible to this credential at that locator. | Check the reference or path against OpenAPI; unknown /api/v1 paths return this code too. |
| `IDEMPOTENCY_REQUIRED` | 400 | A write arrived without an idempotency key. | Add an Idempotency-Key header of 16 to 128 safe characters and resend. |
| `IDEMPOTENCY_CONFLICT` | 409 | The idempotency key is already bound to a different request. | Choose a new key for the new intent, or repeat the original body exactly. |
| `PRECONDITION_REQUIRED` | 428 | A semantic write arrived without a revision precondition. | Read the document, then send its revision in Sponge-If-Revision. |
| `PRECONDITION_FAILED` | 412 | The revision in Sponge-If-Revision is stale. | Read the current document, replan against it, and resend with the new revision. |
| `CONFLICT` | 409 | The current state does not allow this command. | Read the current document or job state before repeating the command. |
| `RATE_LIMITED` | 429 | The credential's request budget is exhausted for now. | Wait for the Retry-After interval, then continue. |
| `TEMPORARILY_UNAVAILABLE` | 503 | A dependency was unavailable or the surface is not activated. | Retry after the Retry-After interval; search and bearer review reads stay unavailable until activated. |
| `REPORT_NOT_READY` | 409 | The research job has not staged its report yet; this is a polling state, not a conflict. | Wait for the Retry-After interval, then read the canonical job until artifacts.report is present. |
| `METHOD_NOT_ALLOWED` | 405 | The path exists but does not implement this HTTP method. | Use one of the methods named in the Allow header for that path. |
| `AGENT_RUN_REQUIRED` | 409 | Standalone proposal submission needs a live research run. | Submit the proposal through a research job instead of the standalone endpoint. |
| `JOB_FAILED` | job state | A research job ended without a report, reported inside the job state. | Read the terminal error; start a new job when it is marked retryable. |
| `INTERNAL_ERROR` | 500 | An unexpected failure that the contract reserves a code for. | Retry once with the same idempotency key, then report meta.requestId. |

## Limits

The numeric limits on requests, documents, attachments, research reports, and tokens.

| Limit | Value | Note |
| --- | --- | --- |
| API request body | 256 KB | Applies to every request; a larger body is INVALID_REQUEST. |
| API response body | 2 MB | A canonical document or report larger than this is not readable through the API. |
| Idempotency-Key and X-Request-Id | 16 to 128 characters | Letters, digits, underscores, and hyphens. |
| Token lifetime | 90 days | A person chooses a shorter expiry on the Agent access page; this is the ceiling. |
| List page | 1 to 50 summaries | Document and research-job lists; the default is 20 summaries. |
| Event page | 256 events | One JSON page of research-job events. |
| Event stream | 20 seconds or 1,024 events | One connection closes after this many seconds or events; the client reconnects after 5 seconds with Last-Event-ID. |
| Research report | 760,000 bytes | The rich report document, with at most 256 Markdown loss issues reported on export. |
| Acceptance contract | 16 coverage requirements, 16 term groups, and eight ratio checks | Optional on a research request; the term groups and coverage requirements a report must satisfy before export. |
| Document outline | 10,000 blocks | The outline stays bounded at this many blocks; large imports apply as one transaction. |
| Chat attachments | Eight files, 20 MB each, 40 MB per turn | PDF, image, JSON, CSV, Markdown, or plain-text files on one turn; attached files do not enter the text-only queue. |

## Changelog

Dated changes to the public API contract and to these docs.

Docs edition 2026.09, reviewed 2 September 2026. The docs are split into Start, Guides, Concepts, Reference, and Status pages as of this edition.

- 2026-09-02: Every path answers unimplemented methods with a JSON METHOD_NOT_ALLOWED (405) and an Allow header. Every operation enumerates the statuses its handler can emit; the working-memory operations carry the ops tag and everything else the agent tag; every component has one example; x-sponge-credential-boundary has one object shape; the event stream framing and caps are published under x-sponge-event-stream; Last-Event-ID is a string header.
- 2026-09-02: New credential scope research:read reads a job, its events, its list, and its Markdown report without research:run; every operation that accepts either scope lists both under x-sponge-required-scopes-any-of. GET /api/v1/research-jobs/{jobId}/report?format=rich-json now also requires document:read. A document or job outside the credential's boundary answers 404 on every route instead of 403.
- 2026-09-02: GET /api/v1/documents/{documentRef} accepts format=blocks (a flat block list with stable IDs, parents, indexes, and per-block Markdown) and format=markdown (a whole-document projection with X-Sponge-Markdown-Loss-Count). DocumentMutationRequest fence fields oldParentBlockId, oldSiblingBlockIds, newSiblingBlockIds, parentBlockIds, and siblingBlockIds are optional; the server derives parents from the exact snapshot and checks any supplied value. Every schema field is described and nested definitions are hoisted to components.schemas.
- 2026-09-02: GET /api/v1/auth returns documentRef and browserHref for a document-bound credential. GET /api/v1/documents and GET /api/v1/research-jobs list summaries with opaque cursors.
- 2026-09-02: meta.requestId and X-Request-Id are always server-minted; a client-supplied X-Request-Id is echoed as meta.clientRequestId. Authenticated responses carry X-Sponge-Requests-Remaining and, when known, X-Sponge-Research-Runs-Remaining. Canonical GETs honor If-None-Match with 304. The report endpoint returns retryable REPORT_NOT_READY with Retry-After instead of CONFLICT. Activation-blocked operations no longer charge the request budget. The principal carries an optional budgets object.

## Other docs pages

- [Start: Start with Sponge](https://sponge.computer/docs/start)
- [Guides: Sponge guides](https://sponge.computer/docs/guides)
- [Concepts: How Sponge knowledge works](https://sponge.computer/docs)
- [Status: Status and limits](https://sponge.computer/docs/status)
- [Sponge developer resources](https://sponge.computer/developer)
- [OpenAPI 3.1](https://sponge.computer/openapi.json)
