docs: add Hub public API reference

This commit is contained in:
Mohamed Boudra
2026-08-04 23:34:41 +02:00
parent dfd18a44a7
commit 0b624b5585
+214
View File
@@ -0,0 +1,214 @@
---
title: Hub public API
description: Use organization API keys to install configuration, dispatch manual runs, and enroll daemons.
nav: Public API
order: 78
category: Hub
---
# Hub public API
The Hub public API lets automation operate on projects and daemons in one
organization. Set the Hub origin in `HUB_URL` below, for example
`https://hub.example.com`.
## Authentication
Create an organization API key from the Hub dashboard under **API keys**. Send
it as a bearer token on every API request:
```http
Authorization: Bearer paseo_pk_...
Content-Type: application/json
```
API keys are organization-scoped. The organization that owns the key determines
which projects and daemon enrollment tokens it can reach; there is no
organization ID to add to these requests. A project slug from another
organization is not accessible through the key.
Each key has one or more selectable scopes:
| Scope | Operation |
| ----------------------- | --------------------------------------------------- |
| `configuration:install` | Replace and activate a project's configuration. |
| `runs:dispatch` | Dispatch a configured manual trigger for a project. |
| `daemons:enroll` | Issue a short-lived daemon enrollment token. |
API keys do not grant dashboard access. They cannot manage connections,
projects, or organization members.
Missing, invalid, or revoked credentials return `401`:
```json
{ "error": "unauthorized" }
```
A valid key without the scope required by an endpoint returns `403`:
```json
{ "error": "forbidden" }
```
## Configuration install
`configuration:install` replaces the project's current configuration with the
supplied YAML after Hub validates and compiles it, then activates the new
revision.
```http
POST /api/configurations/install
```
Request body:
```json
{
"projectSlug": "my-project",
"yaml": "environments:\n - name: production\n kind: daemon\n daemon: build-server\n cwd: /workspace\ntriggers:\n - name: deploy\n on: manual.run\n environment: production\n filters:\n from_users: [automation]\n agent:\n provider: opencode\n mode: full-access\n prompt: Deploy the project"
}
```
The YAML must describe a valid Hub configuration. Replace the example daemon,
working directory, and trigger values with resources in your organization.
On success, Hub returns `201`:
```json
{
"projectSlug": "my-project",
"versionId": "00000000-0000-4000-8000-000000000000",
"version": 3,
"active": true
}
```
Common responses are `400 {"error":"invalid_request"}` for a missing or
malformed body, `404 {"error":"project_not_found"}` for an inactive or
unknown project in the key's organization, and `422` for invalid YAML or an
invalid configuration. An invalid configuration includes the provisional
`versionId` in its response.
Example:
```bash
curl --fail-with-body -sS -X POST "$HUB_URL/api/configurations/install" \
-H "Authorization: Bearer $PASEO_API_KEY" \
-H "Content-Type: application/json" \
--data @configuration-install.json
```
## Manual run dispatch
`runs:dispatch` dispatches a configured `manual.run` trigger for a project.
The trigger must exist in the active configuration, and `actor` must be listed
in that trigger's `filters.from_users` allowlist.
```http
POST /api/manual-runs
```
Request body:
```json
{
"projectSlug": "my-project",
"expectedVersionId": "00000000-0000-4000-8000-000000000000",
"trigger": "deploy",
"actor": "automation",
"deliveryKey": "deploy-2026-08-04-001",
"input": {
"ref": "main"
}
}
```
`expectedVersionId` is optional. When supplied, Hub rejects the dispatch if
that configuration revision is no longer active. `input` is application data
made available to the trigger; it may be any JSON value. Use a unique,
stable `deliveryKey` for each dispatch. Reusing it makes the request resolve to
the existing trigger instead of starting a duplicate run.
On success, Hub returns `200`:
```json
{
"deliveryKey": "deploy-2026-08-04-001",
"triggerId": "00000000-0000-4000-8000-000000000000",
"executionId": "00000000-0000-4000-8000-000000000000",
"status": "spawning",
"daemonId": "00000000-0000-4000-8000-000000000000",
"agentId": "agent-id"
}
```
Common responses are `400 {"error":"invalid_request"}`, `404` for an
unknown project, missing configuration, or missing trigger, `403
{"error":"actor_forbidden"}` when the actor is not allowed by the trigger,
and `409` when the daemon is offline, the expected configuration is no longer
current, or the run could not be dispatched.
Example:
```bash
curl --fail-with-body -sS -X POST "$HUB_URL/api/manual-runs" \
-H "Authorization: Bearer $PASEO_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"projectSlug": "my-project",
"trigger": "deploy",
"actor": "automation",
"deliveryKey": "deploy-2026-08-04-001",
"input": {"ref": "main"}
}'
```
## Daemon enrollment
`daemons:enroll` issues a short-lived enrollment token for a daemon. The API
key mints this token; it is not the daemon's long-lived credential and must not
be used as one.
```http
POST /api/daemons/enrollment-tokens
```
Send an empty JSON object as the request body. On success, Hub returns `201`:
```json
{
"token": "short-lived-enrollment-token",
"expiresAt": "2026-08-04T12:10:00.000Z"
}
```
The token expires after 10 minutes and is consumed when the daemon enrolls.
Pass it to the Paseo CLI, which exchanges it for the daemon's connection
credential:
```bash
ENROLLMENT_TOKEN="$(curl --fail-with-body -sS -X POST \
"$HUB_URL/api/daemons/enrollment-tokens" \
-H "Authorization: Bearer $PASEO_API_KEY" \
-H "Content-Type: application/json" \
--data '{}' | jq -r .token)"
paseo hub connect "$HUB_URL" --token "$ENROLLMENT_TOKEN"
```
An enrollment token cannot be reused. Revoking the API key immediately rejects
future API requests and expires any unconsumed enrollment tokens that key
issued. A race between revocation and issuance is resolved by Hub before a new
token is stored.
## Keys, scopes, and audit information
The complete API-key secret is shown once, immediately after creation. Store it
in your deployment's secret manager; Hub does not show it again. The dashboard
retains only the key's prefix and shows its selected scopes, creation time,
last-used time, and status.
Hub updates `last used` after a key successfully authenticates for a scoped API
operation. API operations retain the key attribution in Hub's audit evidence,
so configuration revisions, manual dispatches, and daemon enrollment tokens
can be traced to the organization key that created them.