Endpoints
This page maps WarmHub’s mounted REST endpoints for repository reads, action observability, component installs, and the MCP and streaming transports. Most rows link to the page that documents the endpoint in detail. A few mounted routes are owned by other pages — see Documented elsewhere below. For base URL, authentication, request and response format, idempotency, and pagination, see the Overview.
Endpoints marked None are publicly accessible for public repositories. Private repositories require a valid Bearer token.
Repository Reads
Section titled “Repository Reads”| Method | Path | Description | Auth |
|---|---|---|---|
GET | /api/repos/:org/:repo/head | HEAD snapshot | None |
GET | /api/repos/:org/:repo/about/:wref | Assertions about a thing | None |
GET | /api/repos/:org/:repo/query | Filtered query | None |
GET | /api/repos/:orgName/:repoName/export | Export repo contents as NDJSON; supports synchronous streaming, async job minting (prefer=async), and async job redemption (token=<exportToken>) | repo:read (unrestricted) and repo:checkpoint-read; not available to component tokens |
Repository Export
Section titled “Repository Export”GET /api/repos/:orgName/:repoName/export
Exports the contents of a repository. The endpoint has three response modes selected by query parameters:
Synchronous NDJSON stream (default)
Omit both prefer and token. The server streams the export as NDJSON directly in the response body.
Async job minting (prefer=async)
Pass prefer=async. The server mints an export job and returns 202 immediately:
{ "exportToken": "<token>", "atRepoSeq": 42 }Use the returned exportToken to poll for completion.
Async job redemption (token=<exportToken>)
Pass token=<exportToken> (the value from the minting response). While the job is still building, the server returns 202. The state field will be either pending (queued, not yet started) or running (actively building):
{ "state": "pending" }{ "state": "running" }Continue polling on any 202 response regardless of the state value.
Once the job is complete, the server returns 200 application/json with a signed download URL and metadata:
{ "url": "<signed-storage-url>", "expiresAt": 1718000000000, "atRepoSeq": 42, "recordCount": 1234, "contentSha256": "<hex digest>"}expiresAt is a Unix timestamp in milliseconds (a JSON number). Download the NDJSON export directly from the url in the response. The URL expires at expiresAt.
Auth: repo:checkpoint-read plus unrestricted repo:read. A token whose repo:read is narrowed to particular refs or shapes gets a 403 from this endpoint even when repo:checkpoint-read is also present — see Personal access tokens for how scope narrowing works.
Component tokens cannot use this endpoint at all. A component call returns 403 on both the synchronous stream and the async paths whatever scopes the token carries, including repo:checkpoint-read with unrestricted repo:read. A component that needs repository bytes must have a user or PAT-backed caller drive the export.
Query parameters:
| Parameter | Values | Description |
|---|---|---|
prefer | async | Mint an async export job instead of streaming synchronously |
token | <exportToken> | Redeem a previously minted async export job |
mode | heads (default) | What to export. heads is the only mode available; ops is not yet available and returns 501 (export-mode-not-enabled) |
sinceRepoSeq | integer, default 0 | Export only what changed after this repository sequence. 0 exports everything |
atRepoSeq | integer | Pin the export to this repository sequence. Omit it and the server pins the current committed sequence and echoes it in the export header, so you can resume against the same pin |
afterDurableId | durable ID | Resume a synchronous stream after the last whole row you received (exclusive). Requires the atRepoSeq the opening header pinned, and formatVersion. Refused with prefer=async or token |
afterVersion | positive integer | With afterDurableId only: when the last row you received was a Shape version, the version number, so the stream continues with that Shape’s later versions |
formatVersion | integer | Required with afterDurableId: the formatVersion from the opening header. A resume whose value does not match the server’s current export format is refused with 412; restart the export instead |
Action Observability
Section titled “Action Observability”| Method | Path | Description | Auth |
|---|---|---|---|
GET | /api/repos/:org/:repo/actions/runs | List action runs | repo:configure |
GET | /api/repos/:org/:repo/actions/runs/:runId/attempts | Get run attempts | repo:configure |
GET | /api/repos/:org/:repo/actions/notifications | List repo-scoped action notification records for terminal failures | repo:configure |
POST | /api/action-runs/:runId/callback | Report async action progress or completion | repo:action-callback (repo-scoped runs); org:action-callback (org-scoped runs) |
MCP And Streaming
Section titled “MCP And Streaming”| Method | Path | Description | Auth |
|---|---|---|---|
POST | /mcp | MCP HTTP transport (GET returns 405) | Bearer token required for some tools; others are accessible without credentials. See MCP Server for details. |
GET | /sse | Server-sent invalidation stream with a live ticket | Live ticket |
POST | /api/repos/:orgName/:repoName/streams/:streamId/submissions | NDJSON streaming submission route | repo:write |
Note: The NDJSON submission route (
/streams/:streamId/submissions) is enabled per repository. On a repository where it is not enabled it answers404— the same response as an unknown path, so a404here does not distinguish “not enabled” from “no such repo”.
Component Registry
Section titled “Component Registry”The first two routes are the install handshake. cli/:method is the transport behind wh component exec — see the CLI reference for how to invoke component methods.
| Method | Path | Description | Auth |
|---|---|---|---|
POST | /api/component-registry/:orgName/:componentName/resolve | Resolve the latest manifest and check install eligibility | repo:write on the install repo |
POST | /api/component-registry/:orgName/:componentName/setup-call | Dispatch the optional registered-component setup callback | repo:write on the install repo |
POST | /api/component-registry/:orgName/:componentName/cli/:method | Dispatch an installed component’s CLI method (via wh component exec) | repo:read on the install repo, plus any per-method permission the method declares; owner-org membership is additionally required when the component is private |
Not Mounted As REST
Section titled “Not Mounted As REST”These surfaces are intentionally documented through SDK, CLI, and MCP workflows rather than REST endpoint references:
| Surface | Use Instead |
|---|---|
| Shape management | SDK shape APIs, wh shape, or commit writes |
| Organization and repository management | CLI org/repo commands or SDK org/repo APIs |
| Repository writes | Writes |
| Subscription management | Subscription CLI/MCP workflows |
| Credential set management | Credential CLI workflows |
| PAT management | Personal Access Tokens guide |
Documented elsewhere
Section titled “Documented elsewhere”A few other mounted routes are documented on the pages that own those surfaces, so they are not repeated here:
| Routes | Documented on |
|---|---|
MCP OAuth metadata — /.well-known/oauth-protected-resource, /.well-known/oauth-protected-resource/mcp, /mcp/.well-known/oauth-protected-resource, /.well-known/oauth-authorization-server | MCP Server |
Raw repository content — /:org/:repo/readme.md, /:org/:repo/agents.md, /:org/:repo/llms.txt | Content shapes |