Component Registry Install Routes
Most callers never use these routes directly: wh component install, the SDK’s client.component.install, and the warmhub_component_install MCP tool each run a complete install or update for you. The two REST routes here cover only two steps of that flow — resolve checks whether a component can be installed into a repo and returns its latest published manifest, and setup-call runs the component’s optional setup callback. They cannot finish an install on their own, so a custom client that needs the whole flow should use the SDK or CLI. Registering and managing components (register, list, view, update, unregister) is not available over REST either; use the SDK’s client.component.registry.* methods.
All routes are mounted under:
/api/component-registry/:orgName/:componentNameThe mounted routes are resolve and setup-call — documented below. A third route, cli/:method, is the transport behind wh component exec; it dispatches an installed component’s CLI methods rather than serving the install or update flow, so it is not documented as a standalone REST call here — see the component CLI reference for how those methods are defined and invoked.
The caller must have the repo:write scope on the install repo named in the request body. Private registered components are installable by members of the owner org into any repo they have write access to.
POST /api/component-registry/:orgName/:componentName/resolve
Section titled “POST /api/component-registry/:orgName/:componentName/resolve”Check whether a registered component can be installed or updated into a repo and return the latest published manifest snapshot. Registered installs resolve the stored manifest snapshot directly through the registry.
Request
Section titled “Request”{ "installRepo": "acme/world"}Response
Section titled “Response”{ "manifest": { "component": { "id": "com.warmhub.Veritas", "name": "veritas", "version": "1.2.0" } }, "manifestHash": "9f86d081884c", "hasSetup": true}manifest is the full resolved manifest object; manifestHash is an opaque version token identifying the published version — treat it as an opaque string and echo it back to setup-call as expectedManifestHash without inspecting or transforming it; hasSetup indicates whether the component declares a setup callback. resolve does not allocate an install id — that is minted by the backend install pipeline.
Errors
Section titled “Errors”400 VALIDATION_ERROR— the body is not valid JSON, orinstallRepois missing or is not an<org>/<repo>string401 UNAUTHENTICATED403 FORBIDDEN— the caller lacks install-repo write access404 NOT_FOUND— registration does not exist, or a private registration is not visible to the caller’s org. Both cases return the same response so a private component’s existence is not leaked409 CONFLICT— the registration has no published manifest version, or the registration is not directly installable (a system-managed component, which the response names explicitly)
POST /api/component-registry/:orgName/:componentName/setup-call
Section titled “POST /api/component-registry/:orgName/:componentName/setup-call”Ask the backend to dispatch the optional setup callback for a registered component install or update. This route supports both fresh installs and registered updates: on update, pass the existing installId together with the manifestHash from the latest resolve response. For a registration that mints tokens, the backend loads the latest published manifest already stored in the registry tables and uses expectedManifestHash to confirm it matches what resolve returned — it does not fetch the manifest from an external source. If the stored manifest has moved since resolve, the call is rejected with 409 CONFLICT; when the hashes match, the backend rotates minted tokens and reruns setup against that stored revision.
Compatibility precondition
Section titled “Compatibility precondition”Send a valid X-WarmHub-Client header on every setup-call request. Its value must be <client-name>/<version> — for example warmhub-cli/1.4.2. The WarmHub SDK and CLI send it for you; raw HTTP callers must set it themselves.
Requests are rejected with 412 CLIENT_INCOMPATIBLE if any of the following are true:
- The header is absent
- The header is malformed (for example, not in
<client-name>/<version>form) - The version is not valid SemVer
- The client family is unrecognized
- The reported version is below that family’s minimum supported floor
The HTTP API overview owns the full 412 contract across routes.
Use a released WarmHub client, which sends the header and keeps it current for you.
Request
Section titled “Request”Send the X-WarmHub-Client header alongside the JSON body:
curl -X POST https://api.warmhub.ai/api/component-registry/acme/indexer/setup-call \ -H "Authorization: Bearer $WARMHUB_TOKEN" \ -H "Content-Type: application/json" \ -H "X-WarmHub-Client: warmhub-cli/1.4.2" \ -d '{ "installId": "019e...", "installRepo": "acme/world", "expectedManifestHash": "9f86d081884c" }'All three fields are required on every request. installId is the id of the ComponentInstall record being set up or updated (minted by the backend install pipeline, not by resolve); pass the manifestHash that resolve returned as expectedManifestHash. For a registration that mints tokens, WarmHub derives setup/runtime token scope from that resolved manifest version, and rejects the call with 409 CONFLICT when the stored manifest has moved since resolve — re-run resolve to pick up the new version. All registrations must include expectedManifestHash on every request; minted-token registrations use it to guard against a changed published manifest.
Response
Section titled “Response”{ "ok": true, "status": 202, "warnings": []}The WarmHub HTTP response status matches the setup dispatch result: 200 when ok is true, otherwise the non-2xx status shown in the JSON body.
On non-2xx setup dispatch:
{ "ok": false, "status": 400, "body": "Webhook target is not reachable or not allowed", "warnings": []}Before outbound dispatch begins, the route can also return the standard WarmHub error envelope:
{ "error": { "code": "FORBIDDEN", "message": "Missing required permissions" }}Handle this envelope for validation, auth, missing setup URL, private-registration visibility, conflict, and manifest/token-preparation failures.
Errors
Section titled “Errors”400 VALIDATION_ERROR— invalid JSON, body fails schema validation, or setup URL is missing401 UNAUTHENTICATED403 FORBIDDEN— the caller lacks install-repo write access, or the registration mints tokens and its manifest requires repo permissions the caller does not hold. The second case lists the shortfall asmissingPermissionsin the error envelope, so check that field before assuming the failure is plain write access404 NOT_FOUND— registration does not exist, or a private registration is not visible to the caller’s org. Both cases return the same response so a private component’s existence is not leaked409 CONFLICT— only for a component whose setup issues tokens to the install. The install cannot go ahead right now, for one of these reasons:- another install of the same component is already running (
Component installation is already in progress) — wait for it to finish, then retry - the component has no published version to install yet
- a newer version was published after you called
resolve— callresolveagain and retry the install - this install attempt is no longer current (for example, it was superseded or expired before setup ran) — start the install again
- another install of the same component is already running (
412 CLIENT_INCOMPATIBLE— theX-WarmHub-Clientheader is missing, malformed, carries a version that is not valid SemVer, names an unrecognized client family, or reports a version below the minimum supported floor for that family. See Compatibility precondition502 BAD_GATEWAY— outbound setup dispatch failed at the network level
- The backend reads
SETUP_*keys from the registered credential set. - When the registration has
mintedTokens: true, the setup payload may include a minted setup token and a runtime token derived from the manifest’sruntimeAccess. Re-runningsetup-callrotates these tokens against the resolved manifest version and revokes the prior ones. - These routes cover only the
resolveandsetup-callsteps of the install pipeline. The reconcile step and install-id minting are handled by the backend; they are not accessible through these REST routes. Custom clients that need the full install flow should use the SDK or CLI. - Custom HTTP clients should pass the
installIdof the install or update being set up, and themanifestHashfrom the precedingresolveresponse asexpectedManifestHash.
Setup credential keys
Section titled “Setup credential keys”The registered credential set can include these setup-auth keys:
| Key | Effect |
|---|---|
SETUP_BEARER_TOKEN | Sends Authorization: Bearer <token> |
SETUP_API_KEY | Sends an API key header |
SETUP_API_KEY_HEADER | Header name for SETUP_API_KEY; defaults to X-API-Key |
SETUP_BASIC_USERNAME + SETUP_BASIC_PASSWORD | Sends HTTP Basic auth when no bearer token is set |
SETUP_SIGNING_SECRET | Sends X-WarmHub-Signature and X-WarmHub-Timestamp; signature is HMAC-SHA256 over <timestamp>.<body> |