Skip to main content
Every route the Sediment server exposes, generated from the committed openapi.yaml by scripts/gen_api_docs.py. Do not edit this file — change the route, then run uv run python scripts/dump_openapi.py followed by uv run python scripts/gen_api_docs.py (CI fails on a stale spec or page). A deployment can also serve the spec itself — /docs, /redoc, /openapi.json — but all three are closed unless docs are enabled. New here? Start with the quickstart; the client side of these routes is the CLI reference.

Conventions

Routers write facts only: no derived state is computed into storage on the request path (ADR 0001). Tenancy binds to the deployment (SEDIMENT_ORG_ID), never to the request — no route accepts an org.
  • Single-fact ingest returns {"fact_id": "<uuid>", "stored": <bool>}. stored: false is a redelivery that collapsed on a UNIQUE index — success.
  • A declined payload returns 200 {"skipped": true, "reason": "<why>"}, so a webhook sender does not retry what will never be stored.
  • Auth failures are 401; a malformed body from an authenticated caller is 400 or 422. A 500 is a bug, never a documented outcome.
  • Every body read is bounded at 25 MiB, before authentication.

Endpoints

Every route, in ingest → read order:

POST /ingest/gateway

Auth: Bearer token from the named SEDIMENT_INGEST_TOKENS map or the legacy $SEDIMENT_API_BEARER_TOKEN. The operator token also permits explicit operator ingest. Missing or invalid credentials return 401; retrieval authority returns 403. Response: Stores one inference-call fact: {"fact_id": "<uuid>", "stored": <bool>}. stored: false means a redelivery collapsed on a UNIQUE index (ADR 0003) — success, not an error. A call whose session cannot be resolved is declined with 200 {"skipped": true, "reason": "no_session"}. Request body — GatewayIngestRequest (application/json): Status codes:

POST /ingest/github/push

Auth: GitHub webhook signature — X-Hub-Signature-256, HMAC-SHA256 over the raw body keyed with SEDIMENT_GITHUB_WEBHOOK_SECRET. The signature is verified before the event type is examined, so a misconfigured webhook cannot green-light itself with a setup ping. Response: {"fact_id": "<uuid>", "stored": <bool>}. A non-push X-GitHub-Event, or a push carrying nothing storable, returns 200 {"skipped": true, "reason": "<why>"} so GitHub stops retrying. A stored push may schedule a background mirror refresh and re-derivation; that result is one log line, never stored (ADR 0001). Parameters: Status codes:

POST /ingest/github/repository

Store an immutable rename receipt independently of mirror availability. Auth: GitHub webhook signature — X-Hub-Signature-256, HMAC-SHA256 over the raw body keyed with SEDIMENT_GITHUB_WEBHOOK_SECRET. The signature is verified before the event type is examined, so a misconfigured webhook cannot green-light itself with a setup ping. Response: {"fact_id": "<uuid>", "stored": <bool>} after storage, including when mirrors are disabled. A declined event returns 200 {"skipped": true, "reason": "<why>"}. Renames never move an identified mirror. Parameters: Status codes:

POST /ingest/github/ci

Auth: GitHub webhook signature — X-Hub-Signature-256, HMAC-SHA256 over the raw body keyed with SEDIMENT_GITHUB_WEBHOOK_SECRET. The signature is verified before the event type is examined, so a misconfigured webhook cannot green-light itself with a setup ping. Response: {"fact_id": "<uuid>", "stored": <bool>} for a completed workflow_run. Any other event, or a run still in flight, returns 200 {"skipped": true, "reason": "<why>"}. Parameters: Status codes:

POST /ingest/github/pull-request

Auth: GitHub webhook signature — X-Hub-Signature-256, HMAC-SHA256 over the raw body keyed with SEDIMENT_GITHUB_WEBHOOK_SECRET. The signature is verified before the event type is examined, so a misconfigured webhook cannot green-light itself with a setup ping. Response: {"fact_id": "<uuid>", "stored": <bool>} for an opened, synchronized, or merged pull request. Another event type, an unmerged closure, or a malformed boundary returns 200 {"skipped": true, "reason": "<why>"}. Parameters: Status codes:

POST /ingest/ci

Auth: Bearer token from the named SEDIMENT_INGEST_TOKENS map or the legacy $SEDIMENT_API_BEARER_TOKEN. The operator token also permits explicit operator ingest. Missing or invalid credentials return 401; retrieval authority returns 403. Response: {"fact_id": "<uuid>", "stored": <bool>}. The envelope forbids unknown fields: a caller naming an org or inventing a field is rejected at the door, not ignored. Request body — VendorCIRequest (application/json): Status codes:

POST /v1/logs

Auth: Bearer token from the named SEDIMENT_INGEST_TOKENS map or the legacy $SEDIMENT_API_BEARER_TOKEN. The operator token also permits explicit operator ingest. Missing or invalid credentials return 401; retrieval authority returns 403. Response: Returns {} — the empty OTLP/HTTP JSON ExportLogsServiceResponse, which means full success. Per-record dedup is invisible to the exporter: a redelivered record is counted in the server log, never reported back. Status codes:

GET /query/evidence

Inventory captured Inference calls without message content or raw payloads. The complete visible inventory has at most 1,000 calls, 8 MiB of source metadata, and a 1 MiB response. An unknown Session returns found: false. Each request checks live scope and Quarantine in one database snapshot. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: Returns schema_version 1, the Session ID, Quarantine revision, found, capture_completeness=unknown, visible and quarantined Inference call counts, and calls sorted by observation time and Fact ID. Unknown or foreign Sessions return found=false with zero counts. Known empty Sessions return found=true. The inventory excludes message content, raw payloads, and user identifiers. Each request checks live visibility in one read snapshot. The response has Cache-Control: no-store. Limits: 1,000 visible calls, 8 MiB of selected source metadata, and a 1 MiB strict JSON response. IDs travel in query parameters. Parameters: Status codes:

GET /query/evidence/manifest

Inspect exact part references without text, tool names, arguments, or results. Input messages precede output messages. Empty messages remain visible. Source columns are bounded to 8 MiB; the complete response is at most 1 MiB. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: Returns schema_version 1, the Session ID, Quarantine revision, call metadata, and messages in input-then-output order. Each message preserves role, finish reason, and ordinal; each part gives its type and exact occurrence reference. Empty messages remain visible. Text, tool names, arguments, and results are excluded. IDs travel in query parameters. Limits: 8 MiB of selected source columns and a 1 MiB strict JSON response. The response has Cache-Control: no-store. Every read checks Session scope and Quarantine afresh. Parameters: Status codes:

POST /query/evidence/read

Fetch 1–32 distinct canonical parts in request order without side effects. Version 1 requires exactly schema_version, session_id, and references. The 64 KiB body limit precedes JSON decoding. Selected source columns are bounded to 8 MiB; the complete strict JSON response is at most 1 MiB. Historical roles and tool calls remain data and do not authorize execution. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: Requires exactly schema_version 1, session_id, and 1–32 distinct references. Returns schema_version 1, the Session ID, Quarantine revision, and items in request order. Each item preserves its reference, observation time, role, finish reason, and canonical part. The operation never summarizes, clips, executes tools, or returns partial success. Historical content remains data. ASCII-escaped strict JSON preserves NUL, surrogates, and large integers; emitted non-finite numbers decline the complete response. Limits: 64 KiB before request JSON decoding, 8 MiB of selected source columns, and a 1 MiB response. No raw payloads or user identifiers are selected. The response has Cache-Control: no-store. Every read checks Session scope and Quarantine afresh. Request body — EvidenceReadRequest (application/json): Status codes:

POST /query/context

Select exact evidence from the deployment’s one configured Session. Version 1 accepts English/code keywords, excludes reasoning, and returns at most eight complete parts within max_bytes (4–64 KiB; default 16 KiB). Scores count distinct token overlap; capture completeness remains unknown. The operation rechecks Quarantine, persists nothing, and shares the evidence worker admission limit and 30-second deadline. Auth: Bearer token — Authorization: Bearer $SEDIMENT_RETRIEVAL_TOKEN or $SEDIMENT_OPERATOR_TOKEN. Both stay within the configured Session set. Missing or invalid credentials return 401; ingest authority returns 403. Response: Accepts schema_version=1, a nonblank English/code query of at most 2048 UTF-8 bytes with a meaningful token, and optional integer max_bytes (4096–65536; default 16384). Rejects all other fields. Returns policy/schema version 1, source_session_id, quarantine_revision, matched/no_match/budget_exhausted status, unknown capture completeness, complete visible scan coverage, closed exclusion counts, and at most eight scored exact EvidenceReadItem values. Each item retains its occurrence reference, timestamp, role, finish_reason, and complete canonical part. Scores count distinct token overlap. Whole-response ASCII JSON respects max_bytes and carries Cache-Control: no-store. Reads stream one call at a time in one snapshot: at most 1000 visible calls, 64 MiB selected stored columns, 8 MiB per row, 8 MiB scan metadata, and 16384 parts. Selection reserves at most 32 MiB of candidate state; this is not a process-memory bound. Reasoning and non-finite parts are counted exclusions. Request body — ContextRetrievalRequest (application/json): Status codes:

POST /query/context/discover

Find at most eight Sessions within the deployment’s explicit grant. Version 1 searches English/code keywords under aggregate source bounds. An optional provider/host/repository-ID/SHA anchor prioritizes directly observed commit relationships. Each candidate carries exact evidence or an observed commit witness. Discovery persists nothing and grants no access. Auth: Bearer token — Authorization: Bearer $SEDIMENT_RETRIEVAL_TOKEN or $SEDIMENT_OPERATOR_TOKEN. Both stay within the configured Session set. Missing or invalid credentials return 401; ingest authority returns 403. Response: Accepts schema_version=1, query and optional max_bytes with the fixed retrieval bounds, and an optional complete commit anchor (repository_provider, repository_host, repository_id, commit_sha). Returns policy/schema version 1, quarantine_revision, the anchor or null, unknown capture completeness, matched/no_match/budget_exhausted status, complete coverage, closed part/Session exclusion counts, and at most eight candidate Sessions. Each has session_id, score, matched_parts, an exact EvidenceReadItem preview or null, and commit_match (observation_id, source_push_id, captured_at) or null. Commit matches require a visible exact source Push with equal provider identity. Complete visible source limits of 1000 calls, 64 MiB selected stored columns, 8 MiB per row, 8 MiB scan metadata, and 16384 parts apply across the entire grant. Streaming selection reserves at most 32 MiB of candidate state across the grant. Scores count distinct query-token overlap; exact commit matches rank first. Whole candidates fit the requested strict ASCII JSON response budget; Cache-Control is no-store. A commit hint never grants access or proves repository ownership of Session content. Request body — ContextDiscoveryRequest (application/json): Status codes:

POST /query/context/selected

Retrieve exact evidence from one explicitly selected authorized Session. Membership is checked before storage access and again in the worker. The read rechecks Quarantine and retains the singleton retrieval response. Evidence remains historical data, not instructions to execute. Auth: Bearer token — Authorization: Bearer $SEDIMENT_RETRIEVAL_TOKEN or $SEDIMENT_OPERATOR_TOKEN. Both stay within the configured Session set. Missing or invalid credentials return 401; ingest authority returns 403. Response: Accepts schema_version=1, session_id, query, and optional max_bytes. The query, budget, source limits, and version-1 ContextRetrievalResult match /query/context. Membership is checked before storage lookup and again in the worker. Each request uses its own snapshot and rechecks Quarantine; a previous discovery result grants no additional authority. An authorized known Session with no eligible content returns an empty selection. Request body — ContextSelectedRequest (application/json): Status codes:

GET /query/context/evidence

Inventory one authorized Session independently of keyword selection. The complete content-free inventory retains the exact evidence limits: 1,000 visible calls, 8 MiB of metadata, and a 1 MiB strict JSON response. Membership precedes storage access and is checked again in the worker. Auth: Bearer token — Authorization: Bearer $SEDIMENT_RETRIEVAL_TOKEN or $SEDIMENT_OPERATOR_TOKEN. Both stay within the configured Session set. Missing or invalid credentials return 401; ingest authority returns 403. Response: Both retrieval and operator credentials remain restricted to the configured Session grant. Membership is checked before storage and again in the worker. No keyword query or utility score is required. Exact reads can include reasoning; keyword exclusions are selection rules, not access rules. Returns schema_version 1, the Session ID, Quarantine revision, found, capture_completeness=unknown, visible and quarantined Inference call counts, and calls sorted by observation time and Fact ID. Unknown or foreign Sessions return found=false with zero counts. Known empty Sessions return found=true. The inventory excludes message content, raw payloads, and user identifiers. Each request checks live visibility in one read snapshot. The response has Cache-Control: no-store. Limits: 1,000 visible calls, 8 MiB of selected source metadata, and a 1 MiB strict JSON response. IDs travel in query parameters. Parameters: Status codes:

GET /query/context/evidence/manifest

Describe exact part references in one authorized Session. Content and raw payloads remain absent. Source columns are bounded to 8 MiB and the complete response to 1 MiB. Each read rechecks Quarantine. Auth: Bearer token — Authorization: Bearer $SEDIMENT_RETRIEVAL_TOKEN or $SEDIMENT_OPERATOR_TOKEN. Both stay within the configured Session set. Missing or invalid credentials return 401; ingest authority returns 403. Response: Both retrieval and operator credentials remain restricted to the configured Session grant. Membership is checked before storage and again in the worker. No keyword query or utility score is required. Exact reads can include reasoning; keyword exclusions are selection rules, not access rules. Returns schema_version 1, the Session ID, Quarantine revision, call metadata, and messages in input-then-output order. Each message preserves role, finish reason, and ordinal; each part gives its type and exact occurrence reference. Empty messages remain visible. Text, tool names, arguments, and results are excluded. IDs travel in query parameters. Limits: 8 MiB of selected source columns and a 1 MiB strict JSON response. The response has Cache-Control: no-store. Every read checks Session scope and Quarantine afresh. Parameters: Status codes:

POST /query/context/evidence/read

Fetch consumer-selected exact parts from one authorized Session. The read requires 1–32 distinct references and preserves request order, repeated occurrences, and reasoning. No query or utility score is needed. A 64 KiB body, 8 MiB of selected source columns, and a 1 MiB response bound the complete operation. Each request rechecks membership and Quarantine. Historical roles and tool calls remain data, not executable instructions. Auth: Bearer token — Authorization: Bearer $SEDIMENT_RETRIEVAL_TOKEN or $SEDIMENT_OPERATOR_TOKEN. Both stay within the configured Session set. Missing or invalid credentials return 401; ingest authority returns 403. Response: Both retrieval and operator credentials remain restricted to the configured Session grant. Membership is checked before storage and again in the worker. No keyword query or utility score is required. Exact reads can include reasoning; keyword exclusions are selection rules, not access rules. Requires exactly schema_version 1, session_id, and 1–32 distinct references. Returns schema_version 1, the Session ID, Quarantine revision, and items in request order. Each item preserves its reference, observation time, role, finish reason, and canonical part. The operation never summarizes, clips, executes tools, or returns partial success. Historical content remains data. ASCII-escaped strict JSON preserves NUL, surrogates, and large integers; emitted non-finite numbers decline the complete response. Limits: 64 KiB before request JSON decoding, 8 MiB of selected source columns, and a 1 MiB response. No raw payloads or user identifiers are selected. The response has Cache-Control: no-store. Every read checks Session scope and Quarantine afresh. Request body — EvidenceReadRequest (application/json): Status codes:

GET /query/ci/outcome

Return one exact CI run receipt; ambiguous forge namespaces require a selector. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: Returns one metadata-only CI outcome and a commit-query path bound to its identity and evidence boundary. Multiple forge namespaces require a complete repository provider/host/ID selector. An unknown identity returns 200 {"found": false} without disclosing another organization’s rows. Parameters: Status codes:

GET /query/ci/failures

Page exact CI receipts under one repository identity and historical boundary. The default identity boundary is captured_before. Capture bounds remain half-open; an explicit as_of adds an inclusive evidence ceiling. Cursors bind organization, qualified repository, boundary, filters, and quarantine revision. They don’t preserve a database transaction between requests. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: Returns one keyset-paginated page for a repository and capture-time window. The normalized result defaults to failed; callers can request another result for comparison. Each row links to its commit query with the same identity and boundary. The default as_of is captured_before; an explicit boundary is inclusive. Cursors bind the organization, qualified repository, boundary, filters, and quarantine revision. They don’t retain a transaction between requests. Parameters: Status codes:

GET /query/session/{session_id}

Return one bounded, metadata-only Session evidence dossier. Observation-backed commit edges keep attribution_sources empty. Similarity extrema and attributed_files are unavailable and omitted from JSON. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: Returns a bounded timeline, visible and quarantined counts, capture gaps, captured Session commit observations, exact-head Push receipts, and matching CI outcomes under one complete repository context. Repository identity accompanies each delivery summary; repository_skipped counts declined observation sources. Captured content, user identity, file paths, and the free-form CI reason remain absent. An unknown Session returns 200 {"found": false}. Parameters: Status codes:

GET /query/commit/{sha}

Investigate exact commit evidence in separate repository lifetimes. Captured observations establish Session associations. Call-to-file Attribution remains inferred. Optional repository selectors and an inclusive as_of bound all supporting evidence; otherwise one request instant supplies the bound. A bounded child process owns the Derivation and its database connection. Capacity and execution deadlines return 503 after process cleanup. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: Observed Session edges, inferred calls and decisions, and exact CI Facts, grouped by repository lifetime with identity and observed names. Unresolved CI remains separate; declined source counts stay visible. Select with a complete provider/host/ID triple or an unambiguous name. An inclusive as_of bounds all supporting evidence. No evidence returns {"commit_sha": "<sha>", "attributed": false} at 200, not an error. The derivation runs per request and is never persisted (ADR 0001). Parameters: Status codes:

GET /v1/me

Auth probe for sediment login: the deployment’s tenant and the API version, reported verbatim so the client can detect skew. Auth: Any configured bearer authority. The response identifies the configured authority and client, never the token. Missing or invalid credentials return 401. Response: {"org_id": "<tenant>", "version": "<api version>", "authority": "<ingest, operator, or retrieval>", "client_id": "<configured client>"}. Retrieval authority also receives source_session_id under singleton configuration or sorted source_session_ids under plural configuration. These identifiers never select tenancy. Status codes:

GET /v1/facts

One entry per FactTable: total rows and the derivation-facing (“visible” = not quarantined) count. Sessions are upserted metadata, not quarantinable facts, so they carry a bare count with no visible column — the same shape sediment facts prints. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: {"sessions": <int>, "tables": {"<table>": {"total": <int>, "visible": <int>}}, "quarantine_revision": <int>}. quarantine_revision is the org’s provenance token: the numeric quarantine-log high-water mark, 0 when nothing is quarantined. Status codes:

GET /v1/facts/session/{session_id}

Fact counts for one session, so a client can verify its own writes without treating unrelated organization-wide totals as evidence. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: {"session_id": "<session id>", "tables": {"<session table>": {"total": <int>, "visible": <int>}}}. The tables are inference calls, developer decisions, edit observations, rejected edits, and retry linkages. The demo command uses these counts so unrelated organization-wide facts cannot mask a dropped demo record. Parameters: Status codes:

GET /v1/facts/session/{session_id}/inference-calls

Return the narrow fields needed to reconcile one Session’s usage. Prompts, responses, raw provider payloads, and user identity stay absent. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: {"session_id": "<session id>", "inference_calls": [{"inference_call_id": "<id>", "model_call_id": "<id or null>", "gateway_provider": "<provider>", "model_provider": "<provider or null>", "model": "<model>", "input_tokens": <int or null>, "output_tokens": <int or null>, "duration_ms": <int or null>}]}. Prompts, responses, raw provider payloads, and user identity are absent. Parameters: Status codes:

GET /v1/facts/session/{session_id}/compatibility-evidence

Return bounded decision, Edit observation, and inference join fields. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: {"session_id": "<session id>", "inference_calls": [{"tool_call_ids": ["<response tool-call id>"]}], "developer_decisions": [{"agent_harness": "<harness>", "accepted": <bool>, "explicit": <bool>, "interaction_mode": "<mode>", "call_id": "<id or null>"}], "edit_observations": [{"agent_harness": "<harness>", "call_id": "<id>"}]}. Captured content, raw payloads, paths, user identity, and Fact identifiers are absent. Parameters: Status codes:

GET /v1/reports/model-outcomes

Return a bounded model-outcome report. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: A version 1 envelope containing the explicit report scope and the canonical base model-outcome report. The route uses the deployment org and doesn’t persist Derivation output. Parameters: Status codes:

GET /v1/reports/accepted-work-lifecycle

Return a bounded accepted-work lifecycle report. Auth: Bearer token — Authorization: Bearer $SEDIMENT_OPERATOR_TOKEN. Missing or invalid credentials return 401; ingest or retrieval authority returns 403. Response: A version 1 envelope containing the explicit report scope and the canonical accepted-work lifecycle report. The route uses the deployment org and doesn’t persist Derivation output. Parameters: Status codes:

GET /health

Auth: None — the liveness probe is unauthenticated. Response: {"status": "ok", "version": "<api version>"}. Status codes: